1、学习C++面向对象编程的virtual析构函数的时候,写了下面的程序
#include<iostream>
using namespace std;
class A
{
public:
A(){
cout << "A is created." << endl;
}
virtual ~A(){
cout << "A is deleted." << endl;
}
};
class B : public A
{
public:
B(){
cout << "B is created." << endl;
}
virtual ~B(){
cout << "B is deleted." << endl;
}
};
int main()
{
A a;
B b;
cout << endl;
A *aPtr = nullptr;
aPtr = &b;
aPtr->~A();
cout << endl;
delete aPtr;
delete (&a);
cout << endl;
}
输出
A is created.
A is created.
B is created.
B is deleted.
A is deleted.
B is deleted.
A is deleted.
A is deleted.
B is deleted.
A is deleted.
A is deleted.
感觉最后三句是多出来的,后来查资料发现
(1)delete乱用了。虽然看输出好像是对的,但是后来再写了几次发现是会出问题的。(new和delete要成对存在)
(2)直接声明对象是不需要手动释放空间的。
2、关于直接声明对象和用new来声明对象的区别
类的定义如下
#include<iostream>
using namespace std;
class A
{
public:
A(){
cout << "A is created." << endl;
}
~A(){
cout << "A is deleted." << endl;
}
};
class B : public A
{
public:
B(){
cout << "B is created." << endl;
}
~B(){
cout << "B is deleted." << endl;
}
};
(1)用new来声明对象。
int main()
{
A *a = new A;
B *b = new B;
cout << endl;
delete (a);
delete (b);
a = nullptr;
b = nullptr;
}
输出
A is created.
A is created.
B is created.
A is deleted.
B is deleted.
A is deleted.
用new声明对象,对象是存储在堆上的。在程序结束后不会自动释放堆上的空间,所以必须要用delete调用其析构函数来回收。delete(a)是直接调用a的析构函数,delete(b)则先调用b的析构函数,再调用a的析构函数。(注意delete之后,要将指针赋值为nullptr,防止野指针的出现)
(2)直接声明对象。
int main()
{
A a;
B b;
cout << endl;
}
输出
A is created.
A is created.
B is created.
B is deleted.
A is deleted.
A is deleted.
直接声明对象,对象是存储在栈中的。当main函数结束后,程序会自动销毁main函数中的所有变量或对象。销毁的顺序和声明的顺序相反(也符合栈的后进先出的特点),故是先销毁b,再销毁a。