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

我的C++单例类返回unique_ptr报错,原因何在?

为什么返回unique_ptr的单例getInstance函数会触发编译错误?

你在实现C++单例时遇到的编译错误,核心原因是std::unique_ptr的独占所有权特性:

问题代码

#include <iostream>
#include <memory>
using namespace std;

class Singleton
{
private:
    static unique_ptr<Singleton> obj;
    Singleton()
    {
        cout << "it's created!!\n";
    }

public:
    ~Singleton()
    {
        cout << "it's desctructed!!\n";
    }
    static unique_ptr<Singleton> getInstance()
    {
        if (obj.get() == nullptr)
            obj.reset(new Singleton());
        return obj;
    }
};
unique_ptr<Singleton> Singleton::obj{nullptr};


int main(){
  
  unique_ptr<Singleton> ss = Singleton::getInstance();
  return 0;
}

编译错误信息

/home/rt7/Desktop/ccProjects/cppTutorial/main.cc: 在静态成员函数‘static std::unique_ptr<Singleton> Singleton::getInstance()’中:
/home/rt7/Desktop/ccProjects/cppTutorial/main.cc:25:16: 错误:使用了已删除的函数‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Singleton; _Dp = std::default_delete<Singleton>]’
   25 |         return obj;
      |                ^~~
从/usr/include/c++/11/bits/locale_conv.h:41包含的文件中,
                 从/usr/include/c++/11/locale:43,
                 从/usr/include/c++/11/iomanip:43,
                 从/usr/include/x86_64-linux-gnu/c++/11/bits/stdc++.h:72,
                 从/home/rt7/Desktop/ccProjects/cppTutorial/main.cc:1:
/usr/include/c++/11/bits/unique_ptr.h:468:7: 注意:在此处声明
  468 |       unique_ptr(const unique_ptr&) = delete;

原因分析

std::unique_ptr是独占式智能指针,它的设计目标是保证同一时间只有一个unique_ptr持有对象的所有权。为了实现这一点,标准库显式删除了它的拷贝构造函数(就是错误信息里提到的unique_ptr(const unique_ptr&) = delete;)。

当你的getInstance函数返回类型是unique_ptr<Singleton>时,return obj;语句会尝试拷贝静态成员obj,但拷贝构造函数已经被禁用,因此编译器直接报错。

而当你把返回类型改为static unique_ptr<Singleton>& getInstance()时,返回的是obj的引用(别名),不会触发拷贝操作,所以编译可以正常通过。

正确的实现思路

单例模式的核心是全局唯一实例,所以不应该把实例的所有权转移出去。推荐的做法:

  • 要么返回unique_ptr<Singleton>&(引用),让外部使用这个引用访问实例,但注意不要让外部通过引用重置指针;
  • 更合理的是直接返回实例的引用,比如static Singleton& getInstance(),内部用局部静态变量实现(更线程安全,也避免手动管理智能指针):
class Singleton
{
private:
    Singleton() { cout << "it's created!!\n"; }
public:
    ~Singleton() { cout << "it's desctructed!!\n"; }
    // 禁止拷贝和移动
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
    Singleton(Singleton&&) = delete;
    Singleton& operator=(Singleton&&) = delete;

    static Singleton& getInstance()
    {
        static Singleton instance; // 局部静态变量,第一次调用时初始化,线程安全(C++11及以上)
        return instance;
    }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 06:45:39