2013-10-22 75 views
0

我有一个关于下面的代码C++参考复制和assingment

#include <iostream> 

using namespace std; 

class A 
{ 
public: 
A & add(A & b); 
}; 

A & A::add(A & z) 
{ 
    A * a = new A(); 
    A & b = *a; 
    cout << "Inside add, address of a: " << &a << endl; 
    cout << "Inside add, address of b: " << &b << endl; 
    cout << "Inside add, address of z: " << &z << endl; 
    A aa; 
    cout << "Inside, add, address of aa: " << &aa << endl; 
    return aa; 
} 


int main() 
{ 

    A *a = new A(); 
    cout << "Original a: " << a << endl; 
    A & b = a->add(*a); 
    cout << "b: " << &b << endl; 
    return 0; 
} 

Q1几个问题。在main,第3行,a->add(*a)中,传递指针* a指向的同一个对象。但在功能A::add(A &)里面,当我试图通过A &b = *a达到相同的效果时,我得到了一个不同的对象。这是为什么? Q2302。在A::add(A &)里面,我将一个非const引用返回给本地对象aa,main获得与本地引用相同的内存地址。因此,这会延长本地参考的生命周期,超出其范围。

Q3。在A::add(A &)内部,我多次提取*a,首先通过A &b = *a,然后通过return *a。在这两种情况下,内存地址总是相同的。这是怎么发生的?您可以检查的&bA::add(A &)输出和结果A &b = a->add(*a)

UPDATE:

  1. 与Q1的问题是,我是在做cout << &a,当我应该做的事情cout << a

  2. 为了消除返回值优化,我使用-fno-elide构造函数编译。我正在使用g ++。

回答

2

A1:您创建了一个新的*带A* a = new A()在主要的aA::adda不同。在主要的a由变量z

A2引用:没有,你在堆上创建a,所以它是会持续下去,直到你对这个变量

A3拨打delete取消引用不会更改存储在指针中的内存位置,它只会获取存储在该位置的值。参考更像是一个别名。所以&b就像是说&(*a)

+0

为Q1,我明白,在main()是不同的对象比函数add()。我的问题是,如果我传递一个函数的引用,正确的对象被传递,但在一个函数中,如果我尝试创建一个对现有对象的引用,我得到一个不同的对象,因此,在函数add() ,a和b的内存地址不同 – Jimm

+0

对于Q2,我更改了代码以显示函数堆栈上的对象正在返回。从内存地址可以看到,堆栈中的对象超出了函数的范围。 – Jimm

+0

您对Q2的更改现在是未定义的行为。它可能在某些情况下工作,但决不是保证 – clcto