C ++:对Singleton类中实例的未定义​​引用

时间:2010-01-27 08:15:52

标签: c++ static singleton linker undefined-reference

我目前正在尝试将工厂实施为单身人士。我几乎使用了Singleton模式的教科书示例。这是.h文件:

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:未定义引用`oxygen :: ImpFactory :: mInstance'

目前有三名学生难过。有什么想法吗?

5 个答案:

答案 0 :(得分:14)

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

cpp文件中,添加以下行:

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

答案 1 :(得分:2)

您需要在cpp文件中定义静态成员。

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

答案 2 :(得分:2)

在你的c ++中添加:

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

答案 3 :(得分:0)

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

如果它是一个类的静态成员,它的构造函数被调用(因为它是一个全局的)如果它是get函数的一个静态成员,它不是构造的,直到它第一次被调用,这减轻了一些人们对单身人士产生的问题以及他们被称为全球化的问题,另一个好处是,大多数连接器将省略get函数,因此如果永远不会调用静态实例,那么你不必担心调用new以便它如果正在使用内存,则仅使用内存。

答案 4 :(得分: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版本而有所不同。