声明对象指针,调用构造、析构函数的多种情况

以下分析一下,声明对象指针,调用构造、析构函数的多种情况,先定义以下的一个基类与派生类。

class CBase
{
public:
	CBase()
    {
		cout << "CBase()" << endl;
	}
    
	~CBase()
    {
		cout << "~CBase()" << endl;
	}
};

class CDerived : public CBase
{
public:
	CDerived()
    {
		cout << "CDerived()" << endl;
	}
    
	~CDerived()
    {
		cout << "~CDerived()" << endl;
	}
};

1、只是声明一个对象指针,没有定义,所以不会分配内存,也不会调用构造函数。如下所示:

CBase *CBase1 = NULL;

/*
输出结果:

(NULL)
*/

2、声明一个基类指针,分配一个派生类对象空间,构造与直接声明派生类一样,析构的话只调用基类的析构函数,而不会调用派生类的析构函数。因为基类的析构函数未声明为虚函数。如下所示:

CBase *pCBase = new CDerived();
delete pCBase;

/*
输出结果:

CBase()
CDerived()
~CBase()
*/

3、在将CBase类的析构函数声明为虚函数时,再执行上述代码如下所示:

CBase *pCBase = new CDerived();
delete pCBase;

/*
输出结果:

CBase()
CDerived()
~CDerived()
~CBase()
*/

所以基类的析构函数必须定义为虚函数,否则子类对象析构时,将无法调用子类的析构函数,造成内存泄露。

4、而声明一个派生类指针,分配一个基类对象空间,会报错,因为基类指针可以指向派生类对象而派生类指针不可以指向基类对象。如下所示:

CDerived *pCDerived = new CBase(); //error
delete pCDerived;

再看下面这个例子:

class CTest
{
public:
	CTest():name("misaka") { } // 初始化列表

	void sayHello() const 
    {
		cout << "hello" << endl;
	}
    
	void showName() const 
    {
		cout << name << endl;
	}

private:
	string name;
};

1、因为只声明一个对象指针,而没有分配内存空间,所以没有给数据成员 name 分配内存,也不会调用构造函数,所以在试图打印 name 时会崩溃。

CTest *PCTest = NULL;
PCTest->sayHello(); //打印出"hello"
PCTest->showName(); //error,造成程序崩溃

2、声明一个对象指针并分配内存空间,就能调用构造函数,不再会崩溃。

CTest *PCTest = new CTest();
PCTest->sayHello(); //打印出"hello"
PCTest->showName(); //OK,打印出"misaka"

3、当然把 name 声明为静态变量也不会崩溃,因为在编译前系统已经给静态成员数据 name 分配了内存,如下所示:

#include "stdafx.h"
#include <iostream>
#include <string>

using namespace std;

string CTest::name = "wangwu"; // 类外要初始化静态变量
class CTest
{
public:
	CTest(){ }

	void sayHello() const 
    {
		cout << "hello" << endl;
	}
    
	void showName() const 
    {
		cout << name << endl;
	}

private:
	static string name;
};

int main()
{
	CTest *PCTest = NULL;
	PCTest->sayHello(); //打印出"hello"
	PCTest->showName(); //OK,打印出"wangwu"

	return 0;
}
/*
输出结果:

hello
wangwu
*/

原文链接: https://www.cnblogs.com/linuxAndMcu/p/10284638.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    声明对象指针,调用构造、析构函数的多种情况

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/288687

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月15日 上午11:10
下一篇 2023年2月15日 上午11:10

相关推荐