0

I have had to simplify some of my code to ask this question. However, in the below code does the fact that I am not declaring x as a reference type mean my change of decrementing will get "forgotten" once the function has exited?

The smartest way to fix this would be to declare x as AnotherClass& x?

void MyClass::myFunc(unordered_map<int, AnotherClass>* dictionary, int z, int y){

    AnotherClass x = dictionary->at(z);

    //Does this change on x get "forgotten" in terms of what dictionary stores
    //once myFunc() has finished, because x is not a reference/pointer type?
    x.changeSomething(y--);
}


class MyClass{
    public:

    private:
        myFunc(unordered_map<int, AnotherClass>* dictionary, int z);
        unordered_map<int, AnotherClass>* dictionary

};
4

2 回答 2

3

正确的。x是 的元素的副本dictionary。您正在对函数本地的副本应用更改。您应该在调用方看不到任何影响。您可以参考,也可以直接对以下调用的结果采取行动at

dictionary->at(z).changeSomething(z--);

请注意,这与函数内部的代码无关。

于 2013-10-27T15:18:17.207 回答
2

在 Java 或 C# 等语言中,当您编写时,Thing t = s;您实际上是在创建一个别名,该别名t引用内存中的同一对象而不是s引用。然而,在 C++ 中,值和别名是严格分开的:

  • Thing t = s;是关于复制s
  • Thing& t = s;是关于创建一个引用相同对象的别名而不是s(引用)
  • Thing* t = &s;是关于创建一个引用相同对象的别名而不是s(指针)

引用和指针之间的区别在这里并不重要,重要的是副本和别名之间的区别。

  • 对副本的更改是该副本的本地更改
  • 通过别名对对象的更改对该对象是本地的,并且通过引用该对象的所有别名可见

就你的例子而言:

// Fix 1: take dictionary by *reference* and not by *pointer*.
void MyClass::myFunc(std::unordered_map<int, AnotherClass>& dictionary, int z, int y){
    // Fix 2: dictionary.at(z) returns a "AnotherClass&"
    // that is an alias to the element held within the dictionary.
    // Make sure not to accidentally make a copy by using that "&"
    // for the type of x.
    AnotherClass& x = dictionary.at(z);

    // "x" is now a mere alias, the following call is thus applied
    // to the value associated to "z" within "dictionary".
    x.changeSomething(y--);
}

请注意,您可以dictionary.at(z).changeSomething(y--);在这种情况下编写;但是有几个缺点:

  • 如果x重复使用不止一次,命名它会更清楚。
  • 在调用的函数/方法有副作用的情况下,调用次数很重要,需要加以控制。
  • 从性能的角度来看,总是欢迎重复避免不必要的计算相同的事情......但不要过于关注性能;)
于 2013-10-27T16:08:20.403 回答