c++ 单例类 析构函数 声明

本文讨论了C++中单例类的析构函数应该声明为public还是private的问题。通过代码示例展示了当析构函数为public时,尝试删除静态实例将导致错误。为了确保安全,建议将析构函数设为private或protected,以防止非法删除。

c++ 的单例类的析构函数应该是public还是非public,请看代码:

#include <stdio.h> 
#include <string.h>
#include <stdlib.h>


class CTest
{
public:
    static CTest& GetInstance()
    {
        static CTest obj;
        return obj;
    }
void Hello()
{
printf("hello -----------\n");
}
~CTest()
{
printf("~CTest() called------\n");
}
private:


CTest()
{
printf("CTest() called------\n");
}
};


int main()  
{  
printf("main is called\n");
CTest::GetInstance().Hello();

delete &(CTest::GetInstance());
printf("main is exit\n");
return 0;  
}  


编译,运行,肯定报错,因为单例对象是static,系统不允许delete的

安全起见,还是声明private,或者protected吧

### 析构函数的介绍 析构函数C++ 类中的一种特殊成员函数,用于在对象的生命周期结束时自动执行资源清理和释放操作。当对象超出作用域、被显式删除或程序结束时,析构函数会被自动调用。默认情况下,编译器会为每个类生成一个默认析构函数,但当类管理资源(如内存、文件)时,需要显式定义析构函数 [^1]。 ### 析构函数的用法 #### 1. 默认析构函数 如果没有显式定义析构函数,编译器会自动生成一个默认析构函数。默认析构函数对内置类型不做处理,对自定义类型会调用其析构函数 [^5]。 ```cpp class Example { // 编译器会自动生成默认析构函数 }; ``` #### 2. 显式定义的析构函数 当类管理资源(如动态分配的内存、打开的文件等)时,必须显式定义析构函数来释放这些资源。 ```cpp class DynamicArray { private: int* data; public: DynamicArray(int size) { data = new int[size]; } ~DynamicArray() { delete[] data; } }; ``` #### 3. 虚析构函数 在继承体系中,为了确保在通过基类指针删除派生类对象时能正确调用派生类的析构函数,需要将基类的析构函数声明为虚函数。 ```cpp class Base { public: virtual ~Base() { // 基类析构函数 } }; class Derived : public Base { public: ~Derived() { // 派生类析构函数 } }; ``` #### 4. 私有析构函数 私有析构函数通常与单例模式结合使用,确保类的唯一实例不可被外部销毁。 ```cpp class Singleton { private: ~Singleton() { // 私有析构函数 } static Singleton* instance; Singleton() {} public: static Singleton* getInstance() { if (instance == nullptr) { instance = new Singleton(); } return instance; } }; ``` #### 5. 删除析构函数(`= delete`) 可以使用 `= delete` 来删除析构函数,禁止对象的销毁。 ```cpp class NonDestructible { public: ~NonDestructible() = delete; }; ``` #### 6. 显式调用析构函数 一般情况下,析构函数会自动调用,但在某些特殊情况下,也可以显式调用析构函数。 ```cpp class MyClass { public: ~MyClass() { // 析构函数 } }; MyClass obj; obj.~MyClass(); ``` #### 7. 显式默认析构函数(`= default`) 可以使用 `= default` 显式要求编译器生成默认析构函数。 ```cpp class MyClass { public: ~MyClass() = default; }; ``` #### 8. 纯虚析构函数 将基类的析构函数声明为纯虚函数可以使基类成为抽象基类,不能直接实例化。但需要注意,即使析构函数声明为纯虚函数,也必须为其提供一个函数体。 ```cpp class Base { public: virtual ~Base() = 0; }; Base::~Base() { // 纯虚析构函数的定义 } ``` ### 析构函数的注意事项 - **资源管理**:若类管理资源(如内存、文件),必须显式定义析构函数来释放这些资源 [^2]。 - **虚析构函数**:在继承体系中,为了确保通过基类指针删除派生类对象时能正确调用派生类的析构函数,基类的析构函数声明为虚函数 [^2][^4]。 - **避免重复释放**:隐式生成的析构函数可能导致浅拷贝问题(如指针成员),需遵循“三/五法则”,即定义析构函数时也需定义拷贝构造和赋值运算符 [^2]。 - **私有析构函数**:私有析构函数常与单例模式结合使用,确保唯一实例不可被外部销毁 [^2]。 - **纯虚析构函数的定义**:纯虚析构函数必须提供实现(函数体,即使函数体为空),否则在派生类析构时会引发链接错误 [^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值