析构函数在下边3种情况时被调用:
- 1. 对象生命周期结束被销毁时
- 2. delete指向对象的指针时,或者delete指向对象的基类类型的指针,而基类析构函数是虚函数
- 3. 对象A是对象B的成员,B的析构函数被调用时,对象A的析构函数也会被调用
类声明如下:
demo.h
class A
{
protected:
int age;
public:
virtual void print();
A(int );
~A();
};
class B : public A
{
public:
void print();
B(int);
~B();
};
class C
{
private:
A a;
public:
C(A temp);
~C();
};
类定义如下:
demo.cpp
A::A(int t):age(t)
{
cout << "constructor A!" << endl;
}
void A::print()
{
cout << "print A!" << endl;
}
A::~A()
{
cout << "destructor A!" << endl;
}
B::B(int t):A(t)
{
cout << "constructor B!" << endl;
}
void B::print()
{
cout << "print B!" << endl;
}
B::~B()
{
cout << "destructor B!" << endl;
}
C::C(A temp):a(temp)
{
cout << "constructor C!" << endl;
}
C::~C()
{
cout << "destructor C!" << endl;
}
测试1
int main()
{
A* a1;
return 0;
}
可以看出,声明指针并不会调用构造函数,也不会调用析构函数。
测试2
int main()
{
A a(10);
return 0;
}
生命周期结束的时候,自动调用析构函数。
测试3
int main()
{
B b(10);
return 0;
}
生成派生类时,先调用基类的构造函数,再调用派生类构造函数。析构函数调用顺序与构造函数调用顺序相反,类似于栈的先进后出原则。
测试4
int main()
{
B* b = new B(10);
return 0;
}
对象使用new创建分配的时候,系统不会自动调用析构函数。所以,此时要手动调用析构函数。
测试5
int main()
{
B* b = new B(10);
delete b;
return 0;
}
使用delete,显示调用析构函数。
测试6
int main()
{
C c(A(20));
return 0;
}
当A对象是C的成员,C的析构函数调用时,也会调用A的析构函数。运行结果中A的析构函数比构造函数多运行一次,是因为在参数传递时,会调用A的复制构造函数(未显示定义,调用默认的复制构造函数)。