C++ 返回的实例变量的地址与实例变量的返回地址

C++ 返回的实例变量的地址与实例变量的返回地址,c++,reference,return-value,C++,Reference,Return Value,如果我有任意类: class myClass { public: int * getAddress() { return &myVar; } int getMyVar() { return myVar; } private: int myVar; }; 假设我想在另一个类中存储变量的地址。如果你这样做有什么区别 int*address=myClassInstance.getAddress() int*地址=&m

如果我有任意类:

class myClass {
public:
    int * getAddress() {
        return &myVar;
    }

    int getMyVar() {
        return myVar;
    }
private:
    int myVar;

};
假设我想在另一个类中存储变量的地址。如果你这样做有什么区别

int*address=myClassInstance.getAddress()

int*地址=&myClassInstance.getMyVar()

我假设这两个都会给我相同的值。有人能解释一下这里到底发生了什么吗

我现在假设的是,我的实例变量实际上没有被返回,而是返回了一个值的副本,所以当我试图访问它的地址时,我实际上是在访问一个随机地址,该地址在函数调用范围之外不再有效。

这是正确的

调用
myClassInstance.getMyVar()
时,它不会返回
myVar
变量本身,而是返回其值的副本

&myClassInstance.getMyVar()
无效,因为不允许您获取临时副本的地址(这将是无用的,因为它将立即销毁,然后您将没有任何地址)。

在这种情况下:

int * address = myClassInstance.getAddress();
通过调用
getAddress()
方法,可以获得
myVar
成员的地址。之后,
address
包含
myVar
成员的地址。到目前为止,一切顺利

然而,在第二种情况下:

int * address = &myClassInstance.getMyVar();

getMyVar()
返回一个临时的
int
,它是
myVar
的副本。然后,您尝试获取这个临时变量的地址,而不是
myVar
,它应该会生成一个值。

您的假设是正确的。第一个是成员的有效地址。第二个是在堆栈上创建的临时值的“随机”堆栈地址。值得注意的是,如果您更改:

int getMyVar() {
    return myVar;
}


code
int*address=&myClassInstance.getMyVar()
完全有效,并产生与
int*address=myClassInstance.getAddress()相同的结果,第二个不应在符合标准的编译器上编译。@juanchopanza-标准不要求编译器拒绝编译该代码。它需要编译器发出诊断信号。@PeteBecker是的,很公平。“不应在至少未发出诊断的情况下进行编译”。@juanchopanza实际上是使用VS进行编译的2015@Archmede是的,这是一个非标准的编译器“扩展”。您可能会找到一个设置来强制VS变得更合理。实际上,由于引用是隐藏的指针,您可以使用右值引用获取临时的地址。
int &getMyVar() {
    return myVar;
}