0

我正在按照此处第一个答案中描述的方式实施 Singleton。getInstance() 方法返回一个引用,但我不确定我应该如何创建我的新实例并在创建它并返回它之前检查它是否已经存在。

class Song {

private:
    Song song;
    Song();
    Song(Song const&); // don't implement
    void operator = (Song const&); //don't implement

public:
    static Song &getInstance();
}

那么我的getInstance();实现应该是什么样的呢?如果歌曲成员对象已经存在,我想返回它,否则创建它然后返回它。我知道我添加的链接中有一个实现,但我不确定它是否符合我的要求,而且我不太了解它。

另外,有人可以解释这两行的用途以及为什么=要覆盖运算符吗?

    Song(Song const&); // don't implement
    void operator = (Song const&); //don't implement
4

3 回答 3

1

实施在您引用的答案中:

static S& getInstance()
{
    static S    instance; // Guaranteed to be destroyed.
                          // Instantiated on first use.
    return instance;
}

该实例是静态的,因此它在第一次调用getInstance()函数时被实例化。

有关更多信息,请参阅此相关 SO 问题

关于第二个问题的说明。第一个是复制构造函数:

Song(Song const&);

如果要初始化一个对象以获取另一个对象的值,则需要它:

Song a;
Song b = a; // calls copy constructor

第二个是赋值运算符:

void operator=(const Song&);

为已经存在的实例赋值需要:

Song a;
Song b;
b = a; // calls assignment operator.

请注意,赋值运算符的标准返回值是参考:

Song& operator=(const Song&);
于 2012-07-26T13:57:51.967 回答
1

那么我的 getInstance(); 应该怎么做?实现是什么样的?如果歌曲成员对象已经存在,我想返回它,否则创建它然后返回它。

这正是您链接的代码所做的。引用这个答案:

static S& getInstance()
{
    static S    instance; // Guaranteed to be destroyed.
                          // Instantiated on first use.
    return instance;
}

正如评论所说,它是在首次使用时实例化的;这就是函数范围内的静态变量的工作方式。

与实现 Singleton 反模式的这种特定尝试相关的致命陷阱是,在它被销毁后可以访问它,例如从另一个静态对象的析构函数中访问它。

另外,有人可以解释这两行的用途以及 = 运算符被覆盖的原因吗?

这些是为了防止复制对象。复制可以使用复制构造函数(创建新对象)或复制赋值运算符(覆盖现有对象)来完成;如果这些被声明为私有且未实现,则无法复制实例。在 C++11 中,可以通过删除它们来使其更加明确:

Song(Song const&) = delete;
void operator = (Song const&) = delete;
于 2012-07-26T13:59:47.217 回答
0

为了回答第二个问题,这两行将复制构造函数和赋值运算符声明为私有,因此它们不能被调用。如果没有这两行,编译器将生成这些的默认实现,并且客户端可以创建副本,从而违背了Singleton模式的目的。

于 2012-07-26T14:00:22.203 回答