析构函数小结

析构函数在以下3种情况时被调用:

  • 1. 对象生命周期结束被销毁时
  • 2. delete指向对象的指针时,或者delete指向对象的基类类型的指针,而基类析构函数是虚函数
  • 3. 对象A是对象B的成员,B的析构函数被调用时,对象A的析构函数也会被调用

类声明:

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();
};

类定义:

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;
}
//结果constructor A!
//destructor A!

生命周期结束的时候,自动调用析构函数。

测试3:

int main()
{
    B b(10);
    return 0;
}
//结果

constructor A!
constructor B!
destructor B!
destructor A!

 

生成派生类时,先调用基类的构造函数,再调用派生类构造函数。析构函数调用顺序与构造函数调用顺序相反,类似于栈的先进后出原则。

测试4:

int main()
{
    B* b = new B(10);
    return 0;
}

//结果
constructor A!
constructor B!

对象使用new创建分配的时候,系统不会自动调用析构函数。所以,此时要手动调用析构函数。

测试5:

int main()
{
    B* b = new B(10);
    delete b;
    return 0;
}
//结果
constructor A!
constructor B!
destructor B!
destructor A!

使用delete,显示调用析构函数。

测试6:

int main()
{
    C c(A(20));
    return 0;
}
//结果
constructor A!
constructor C!
destructor A!
destructor C!
destructor A!
 
 

当A对象是C的成员,C的析构函数调用时,也会调用A的析构函数。运行结果中A的析构函数比构造函数多运行一次,是因为在参数传递时,会调用A的复制构造函数(未显示定义,调用默认的复制构造函数)。

猜你喜欢

转载自www.cnblogs.com/inception6-lxc/p/9365629.html