声明对象指针,调用构造、析构函数的多种情况
以下分析一下,声明对象指针,调用构造、析构函数的多种情况,先定义以下的一个基类与派生类。
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
*/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探