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

从类成员返回智能指针的正确方式?Person类单例模式实现疑问

实现Person类的单例模式(C++版)

嘿,我看你已经摸到了单例模式的核心思路,但代码还没写完,而且有个容易踩的小坑,我来帮你补全并把细节说清楚,确保这个Person类真的只能生成一个实例,还能在程序任何地方安全访问。

先给你补全并修正后的代码(基础版)

首先是类的声明和实现,我调整了返回值的类型,避免unique_ptr的所有权转移问题:

头文件部分

#include <memory>

class Person {
    // 静态成员存储唯一实例,用unique_ptr自动管理内存
    static std::unique_ptr<Person> instance;

    // 把构造、拷贝、赋值都设为私有/禁用,确保外部不能随便创建或拷贝实例
    Person() = default;
    Person(const Person&) = delete;
    Person& operator=(const Person&) = delete;
    ~Person() = default;

public:
    // 返回实例的引用,避免所有权被转移
    static Person& getInstance();
};

源文件实现部分

// 必须在类外初始化静态成员变量
std::unique_ptr<Person> Person::instance = nullptr;

Person& Person::getInstance() {
    // 第一次调用时才创建实例
    if (!instance) {
        instance = std::make_unique<Person>();
    }
    // 返回引用,让外部能访问实例但拿不到所有权
    return *instance;
}

为什么要这么改?

  • 不能直接返回unique_ptr:unique_ptr是独占所有权的智能指针,如果返回它,每次调用getInstance()都会把instance的所有权转移出去,下次调用时instance就变成空指针了,会重新创建新的Person实例——这直接破坏了单例的唯一性!返回引用就不会有这个问题。
  • 禁用拷贝和赋值:如果不禁用,别人可能通过拷贝构造或者赋值运算符偷偷创建新的实例,单例就白做了。
  • 用unique_ptr管理内存:不用手动写delete,程序结束时会自动释放实例内存,避免内存泄漏。

更推荐的线程安全版本(C++11及以后)

上面的基础版有个问题:如果多个线程同时调用getInstance(),可能会创建多个实例(因为if (!instance)的检查不是原子操作)。C++11之后,静态局部变量的初始化是线程安全的,我们可以利用这一点写更简洁、安全的代码:

#include <memory>

class Person {
    // 同样禁用构造、拷贝、赋值
    Person() = default;
    Person(const Person&) = delete;
    Person& operator=(const Person&) = delete;
    ~Person() = default;

public:
    static Person& getInstance() {
        // 静态局部变量,第一次调用时自动初始化,且C++11保证这个初始化过程是线程安全的
        static std::unique_ptr<Person> instance = std::make_unique<Person>();
        return *instance;
    }
};

这个版本不需要在类外初始化静态成员,代码更紧凑,还天然线程安全,非常推荐。

怎么使用这个单例?

在程序任何地方,你只需要调用Person::getInstance()就能拿到唯一的Person实例,比如:

// 获取实例并调用成员方法(假设Person有sayHello方法)
Person::getInstance().sayHello();

// 或者存一个引用,方便后续使用
Person& p = Person::getInstance();
p.doSomething();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 11:13:33