关于这个问题,曾经讨论过,apnic也总结过关于“在构造函数中调用构造函数”的问题。
#include <iostream>
using namespace std;
class A
{
public:
A();
A(int i);
int data;
~A();
};
A::A()
{
cout<< " call A::A() " << endl;
data = 0;
}
A::A(int i)
{
cout<< " call A::A(int) " << endl;
data = i;
}
A::~A()
{
cout<< " call A::~A() " << endl;
}
class B:public A
{
public:
B();
B(int i);
~B();
};
B::B(int i)
{
cout<< " call B::B(int) " << endl;
B();
}
B::B():A(10)
{
cout<< " call B::B() " << endl;
}
B::~B()
{
cout<< " call B::~B() " << endl;
}
void main()
{
B b(2);
cout<< b.data << endl;
}
一般认为B b(2);应该调用B::B(int i)构造函数,里面调用B();
而B::B()调用的是A(10)构造函数,A::A(int i)会把data设置成i,就是10。
但是运行结果是0:
call A::A() //调用B(int)之前,先调用基类的缺省构造函数
call B::B(int) //调用B(int)
call A::A(int) //由于B()中使用了初始化列表,这里先调用了A(int)
call B::B() //然后才调用了B()
call B::~B() //居然调用析构函数
call A::~A() //自然也会调用基类的析构函数
0 //结果
call B::~B() //再次析构,销毁对象
call A::~A()
从上面的调用过程中,可以看到只要调用类的构造函数,就会在栈中创建对象,是这样子的么?
但是如果改成构造函数中调用父类的构造函数:
B::B(int i)
{
cout<< " call B::B(int) " << endl;
A::A(i); //call this constructor.
}
运行结果是:
call A::A()
call B::B(int)
call A::A(int)
call A::~A()
0
call B::~B()
call A::~A()
少了对B的构造函数和析构函数的调用,但是仍然调用了~A(); 这是为什么?
看来只能改成这样:
B::B(int i):A(i)
{
cout<< " call B::B(int) " << endl;
}
运行结果是:
call A::A(int)
call B::B(int)
2
call B::~B()
call A::~A()
只有这个结果是正确的,难道父类的构造函数只能在初始化列表中使用?