class Foo{
void operator=(const Foo&){};
public:
Foo(){};
};
Foo& fooRef(){
static Foo aFoo;
return aFoo;
}
int main() {
Foo &foo = fooRef();
return 0;
}
此代码正常运行,不会发出任何错误。一旦我将主体改为:
int main(){
Foo &foo;
foo = fooRef();
return 0;
}
编译器尝试使用operator=
因此抱怨。所以我的第一个问题是:它为什么会有所作为?
我到达这个事实的方式是我正在使用CPPunit
进行单元测试,我必须测试一个签名为getInstance()
为Singleton& getInstance()
的单例类。为了进行测试,我试图在TestSingleton
类中以单例形式初始化一个实例。因此:
class TestSingleton{
...
private:
Singleton &instance;
};
void TestSingleton::setUp(){
this->instance = Singleton::getInstance();
}
上面的例子发出了一个错误(因为operator=
被声明为私有,如果它不是,很明显我不会被调用)。所以第二个问题是:我如何避免这种情况并在TestSingleton
类中获得单例实例?
答案 0 :(得分:5)
参考既不能默认初始化也不能重新定位。他们必须从一开始就引用一个现有的对象。它们只是另一个对象的别名。
所以第二个问题是:我如何避免这种情况并在
TestSingleton
类中获得单例实例?
您可以使用构造函数初始化列表初始化引用成员:
class TestSingleton{
...
TestSingleton(Singleton& s) : instance(s) {}
private:
Singleton &instance;
};
如果您发现需要能够默认初始化然后重新定位"引用",则应使用指针或可选类型(例如,请参阅boost::optional
) 。但在这种特殊情况下,由于您正在处理单例,因此实际上不需要存储对它的引用。您可以随时使用Singleton::getInstance()
。