关于C++析构函数问题,在线等答案,急
[解决办法]
C(A a, B b)//这里执行一次
C c(A(1), B(2))//这里执行一次
[解决办法]
第一次是A(1)、B(2)的,第二次是C构造函数中的a和b的。
[解决办法]
你在主线程中定义了一个C对象。
你在C对象中,定义了一个成员变量A*,成员变量B*,未释放,故不会析构。
你在C的构造函数中定义了一个局部变量A,局部变量B,调用此构造函数的时候,A,B都各有一次构造,一次析构。
你在main中对C进行初始化的时候,构造了一个A,B,各有一次构造,一次析构。
[解决办法]
第二次的构造函数仅仅是为了复制参数,因为您使用的是传值。如果是引用就不会
[解决办法]
体会下这个
class C
{
public:
C(A *a, B *b)
{
pA = new A(a->i);
pB = new B(b->j);
}
~C(){cout<<"C disconstruct!"<<endl;}
A* pA;
B* pB;
};
int main()
{
C c(&A(1), &B(2));
return 0;
}
[解决办法]
楼主听说过NRVO没?自定义复制构造函数和临时对象是运行期类对象模型性能下降的重要原因,为了提高性能,二十多年前C++编译器的设计者就设计了NRVO优化,至今仍然被很多编译器采用。
NRVO优化抑制了自定义复制构造函数,不使用临时对象而直接在目标对象上运行构造函数。
对于楼主的例子,本来会先构造A("Hello")和B("World")两个临时对象,然后通过复制构造函数初始化C构造函数内的a和b两个对象,NRVO被编译器启用后(条件是客户自定义了复制构造函数,否则没有必要启用),自定义复制构造函数不再运行,且不产生A("Hello")和B("World")两个临时对象,而是将A("Hello")和B("World")直接在a和b上构造,由于少了两个临时对象,因此仅看见一次析构。
[解决办法]
C(A a, B b)
{
pA = new A(a.i);
pB = new B(b.j);
}
传参时,发生拷贝,离开构造函数后, 拷贝的临时对象就被析构了。
main函数中的 A(1) B(2) 离开 main时 也分别析构。
正确的作法如下:
class A
{
public:
A(int i){this->i = i;}
~A(){cout<<"A disconstruct!"<<endl;}
int i;
};
class B
{
public:
B(int j){this->j = j;};
~B(){cout<<"B disconstruct!"<<endl;}
int j;
};
class C
{
public:
C( const A & a, const B & b)
{
try
{
pA = new A(a.i);
pB = new B(b.j);
}
catch ( ... )
{
if ( pA ) delete pA;
if ( pB ) delete pB;
}
}
~C()
{
if ( pA ) delete pA;
if ( pB ) delete pB;
cout<<"C disconstruct!"<<endl;
}
A* pA;
B* pB;
};
int main()
{
C c(A(1), B(2));
return 0;
}
仅供参考
[解决办法]
C c(A(1), B(2));
1)B tmpB(2);
2)A tmpA(1);
3)C tmpC(tmpA,tmpB);
4)B b=B(tmpB);-->push tmpB
5)A a=A(tmpA); -->push tmpA
6)tmpA.~A(); // ====>A disconstruct!
7)tmpB.~B(); // ====>B disconstruct!
8)pA = new A(a.i);
9)a.~A(); // ====>A disconstruct!
10)pB = new B(b.j);
11)b.~B(); // ====>B disconstruct!
12)tmpC.~C(); //C disconstruct!
pB
pA 两个指针没有delete 所以没有析构;这个是内存泄露。
这是程序的运行过程!!!
[解决办法]
我说的一次指的就是class A和class B都各只析构一次,不是合起来只有一次。
至于你的问题,我上面已经说了,就是编译器启用了NRVO的原因,NRVO是不会理会复制构造函数的副作用的。