2010-01-27 81 views
7

我目前正在试图将一个工厂实现为一个单例。我实际上使用了Singleton模式的教科书示例。这里的.h文件:C++:在Singleton类中未定义对实例的引用

namespace oxygen{ 

class ImpFactory{ 

public: 
    static boost::shared_ptr<ImpFactory> GetInstance(); 

private: 
    static boost::shared_ptr<ImpFactory> mInstance; 
}; 

和这里的.cpp文件:

#include "impfactory.h" 

using namespace oxygen; 
using namespace boost; 

shared_ptr<ImpFactory> ImpFactory::GetInstance(){ 
    if (mInstance.get() == 0) 
     mInstance = shared_ptr<ImpFactory>(new ImpFactory()); 
    return mInstance; 
} 

代码编译,但我得到一个链接错误:

../../lib/oxygen/liboxygen.so.3.2.4: undefined reference to `oxygen::ImpFactory::mInstance'

这个目前有三个学生难倒。有任何想法吗?

回答

13

您必须定义静态实例,不只是声明它。该定义创建您引用的实际对象。

在你cpp文件,添加一行:

boost::shared_ptr<ImpFactory> ImpFactory::mInstance; 
2

您需要为一个CPP文件的静态成员的定义。

boost::shared_ptr<ImpFactory> ImpFactory::mInstance; 
2

在C++补充一点:在另一个方面说明

boost::shared_ptr<ImpFactory> ImpFactory::mInstance; 
0

,也许你应该做的实例指针get函数而不是类的静态成员,这并没有什么太大当你使用新的/指针方法时有很大的不同。但如果你只是创建一个静态实例(即不使用指针,并从get get函数返回对它的引用),这会产生很大的差异,因为:

如果它是一个类的静态成员,其构造函数是如果它是get函数的一个静态成员,它就不会被构造,直到它被称为第一次,这就缓解了人们对单例的一些问题,并且它们被全球化所美化,另一件好事是,大多数连接器会省略get函数,因此如果它永远不会被调用,它将完全忽略静态实例,因此您不必担心调用new以便它只在使用时才使用内存。

0

由于您使用了Boost,因此您可能需要考虑Boost单例类。退房:

#include <boost/serialization/singleton.hpp> 

using namespace boost::serialisation; 

struct MyClass : public singleton<MyClass> 
{ string name_; int age_; }; 

int main(int argc, char* argv[]) 
{ 
    MyClass::get_mutable_instance().name_ = "Robin"; 
    MyClass::get_mutable_instance().age_ = 21; 
} 

您使用哪个取决于您正在做什么。虽然通常情况下我有点反单身,但在可能的情况下重复使用是有意义的。尽管有一个警告:Boost单例似乎已经在库中移动了一段时间,所以这可能取决于您使用的Boost版本。

+0

我觉得它没有那么多的“感动”,因为“有人认为他们想要一个单身人士时增加了,然后当他们意识到这毕竟不是一个好主意时就被删除了”。 – 2010-01-27 16:23:11

相关问题