c ++ 11 Singleton正在创建新实例

时间:2017-07-24 11:42:38

标签: c++ c++11

这是我的单身人士

class MySingleton {
private:
    int myNumber;
public:
    static MySingleton &get() {
        static MySingleton instance;
        return instance;
    }

    int getMyNumber() const {
        return myNumber;
    }

    void setMyNumber(int myNumber) {
        MySingleton::myNumber = myNumber;
    }
};

这是测试它的代码

MySingleton t1 = MySingleton::get();
t1.setMyNumber(6);
printf("t1: %d \n", t1.getMyNumber());

MySingleton t2 = MySingleton::get();
printf("t2: %d \n", t2.getMyNumber());

现在我得到的输出是

t1: 6 
t2: 0 

但预期结果将是

t1: 6 
t2: 6 

看起来MySingleton::get()正在创建一个新实例,当然不应该这样做。

4 个答案:

答案 0 :(得分:6)

在您的情况下,get()不会创建副本。 t1t2的分配正在进行中。为避免将其更改为引用:MySingleton& t1 = MySingleton::get()

为了避免意外错误,请删除复制和赋值运算符:

MySingleton(const MySingleton& other) = delete;
MySingleton& operator=(const MySingleton& other) = delete;

答案 1 :(得分:2)

原因是您在这些行中创建了实例的副本:

MySingleton t1 = MySingleton::get();
MySingleton t2 = MySingleton::get();

并更改副本。

要使其正常工作,您必须添加引用:

MySingleton& t1 = MySingleton::get();
MySingleton& t2 = MySingleton::get();

另请注意,经典的单例设计假定删除了复制构造函数和复制赋值运算符以避免此类错误:

class MySingleton {
    private:
        // ...
    public:
        // ...
        MySingleton(const MySingleton&) = delete;
        void operator=(const MySingleton&) = delete;
};

P.S。您可能会发现this discussion很有用。它显示了使用 C ++ 的单例模式的实现细节。

答案 2 :(得分:0)

您正在复制单例而不是获取引用:

MySingleton &t1 = MySingleton::get();

将copy-a move-assignment和-constructors标记为delete并将构造函数和析构函数设为私有:

class MySingleton
{
public:
    MySingleton(const MySingleton&) = delete;
    void operator=(const MySingleton&) = delete;

    MySingleton(MySingleton&&) = delete;
    void operator=(MySingleton&&) = delete;

private:
    MySingleton() = default;
    ~MySingleton() = default;

};

请注意,您可能只需要一个全局变量而不是单个变量。

答案 3 :(得分:0)

您将t1和t2都声明为类的实例,而不是对类的引用。

正确实现了get函数,但随后在赋值时构造了每个实例。 请注意,将构造函数设置为私有可以防止编译时出现此错误。

我建议您阅读一篇关于如何在c ++中实现Singletons的教程,以学习一些好的实践,或者只是使用现有的精心制作的实现。