You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

已禁用所有拷贝相关构造,为何仍能复制单例实例?

单例模式的常见误解:指针赋值≠创建新实例

你完全搞错了——SingleTone *ss = SingleTone::instance();这段代码根本没有生成第二个单例实例。它只是把指向唯一单例对象的内存地址复制给了新的指针变量ss,本质上ss和instance()返回的指针指向的是同一个对象,并不是两个独立的实例。

为什么你的类成员限制没起作用?

你删除的拷贝构造函数、赋值运算符都是针对对象本身的操作,比如禁止SingleTone s = *SingleTone::instance();这种直接拷贝对象的行为。但指针赋值是C++的基础语法,和类的特殊成员函数无关:指针只是个存储内存地址的普通变量,复制指针只是复制地址值,不会触发类的任何拷贝或赋值逻辑。

你的单例实现还有两个明显问题

  1. 线程不安全:instance()里的if (singletone == nullptr)判断在多线程环境下可能被多个线程同时进入,导致多次执行new SingleTone(),最终创建多个实例,违背单例的初衷。
  2. 内存泄漏:你用new创建了单例对象,但没有对应的delete操作,程序退出时这个对象不会被自动销毁,造成内存泄漏。

更可靠的单例实现方案

推荐使用C++11及以上支持的局部静态变量懒汉式,既保证线程安全,又无需手动管理内存:

class SingleTone
{
public:
    // 彻底禁止对象的拷贝、移动与赋值
    SingleTone(const SingleTone&) = delete;
    SingleTone(SingleTone&&) = delete;
    SingleTone& operator=(const SingleTone&) = delete;
    SingleTone& operator=(SingleTone&&) = delete;

    // 返回引用而非指针,避免用户混淆指针赋值和对象创建
    static SingleTone& instance()
    {
        // C++11标准保证局部静态变量的初始化是线程安全的
        static SingleTone instance;
        return instance;
    }

    int get1()
    {
        return 1;
    }

private:
    SingleTone() = default;
};

使用时直接通过SingleTone::instance().get1()调用,或者用引用接收:SingleTone& s = SingleTone::instance();,这样就不会再产生“创建多个实例”的误解。

内容的提问来源于stack exchange,提问作者user63898

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 12:25:14