使用静态成员实现C++单例却得到不同对象地址的问题
为什么我的静态成员单例返回的对象地址不一样?
你的单例实现的核心逻辑其实是正确的——getInstance()函数里的static std::unique_ptr<singleton>只会被初始化一次,指向的是同一个堆上的singleton对象。问题出在变量声明的类型推导上:
你在main里写的:
auto inst1 = singleton::getInstance(); auto inst2 = singleton::getInstance();
这里的auto会被C++编译器推导为singleton(值类型),而不是singleton&(引用类型)。这意味着每次调用getInstance()返回的对象引用,都会被用来拷贝构造一个新的局部对象,inst1和inst2是完全独立的栈上拷贝,它们的地址自然不同。
解决方法
有两种方式可以修复这个问题:
显式声明引用类型
把auto改成auto&,让inst1和inst2直接绑定到getInstance()返回的同一个对象上:int main() { auto& inst1 = singleton::getInstance(); auto& inst2 = singleton::getInstance(); cout << &inst1 << endl; cout << &inst2 << endl; return 0; }这样输出的两个地址会完全一致。
从根源禁用拷贝操作
为了避免后续再出现类似的意外拷贝错误,可以把单例类的拷贝构造函数和赋值运算符显式删除,让编译器直接阻止拷贝行为:struct singleton { // 禁用拷贝构造与赋值 singleton(const singleton&) = delete; singleton& operator=(const singleton&) = delete; // 可选:禁用移动构造与赋值,进一步强化单例特性 singleton(singleton&&) = delete; singleton& operator=(singleton&&) = delete; static auto& getInstance() { static auto instance = std::make_unique<singleton>(); return *instance; } };此时如果再写
auto inst1 = singleton::getInstance(),编译器会直接抛出错误,从源头杜绝错误的发生。
内容的提问来源于stack exchange,提问作者Troskyvs
相关产品推荐
相关产品推荐

