C ++ Singleton:`未定义引用`错误

时间:2015-01-23 14:36:03

标签: c++ singleton

我正在尝试在没有内存分配的情况下实现单例设计模式。我试图寻找一个解决方案,但似乎每个解决方案都是针对使用内存分配定义的单例。

我将构造函数设为私有,并且我添加到头文件中的唯一代码是使其成为单例设计模式:

static ParametersServerPC& ParametersServerPC::GetInstance() {

    static ParametersServerPC instance;
    return instance;

}

这是来自基类ParametersServerABS的派生类,它具有空的构造函数定义。 ParametersServerABS是一个抽象类。

当我尝试在单独的文件中实例化ParametersServerPC类时:

ParametersServerPC& paramServer = ParametersServerPC::GetInstance();

我收到此错误:

undefined reference to `ParametersServerPC::GetInstance()'

以下是.cpp.hpp个文件:

parameters_server_abs.hpp:

#ifndef PARAMETERS_SERVER_ABS_HPP_
#define PARAMETERS_SERVER_ABS_HPP_

class ParametersServerABS {

    public:

        ParametersServerABS();

        ~ParametersServerABS();

        virtual bool Load() = 0;

};

#endif

parameters_server_abs.cpp:

#include "mid_level/parameters_server_abs.hpp"

ParametersServerABS::ParametersServerABS() {}

ParametersServerABS::~ParametersServerABS() {}

parameters_server_pc.hpp:

#ifndef PARAMETERS_SERVER_PC_HPP_
#define PARAMETERS_SERVER_PC_HPP_

#include <string>

#include "mid_level/parameters_server_abs.hpp"

class ParametersServerPC: public ParametersServerABS {

    public:

        ~ParametersServerPC();

        static ParametersServerPC& GetInstance();

        virtual bool Load();

   private:

        ParametersServerPC(std::string parameterFileName = "parameters.txt");

        std::string _parameterFileName;

};

parameters_server_pc.cpp:

#include "mid_level/parameters_server_pc.hpp"

ParametersServerPC::ParametersServerPC(std::string parameterFileName = "parameters.txt") :
        _parameterFileName(parameterFileName) {

}

ParametersServerPC::~ParametersServerPC() {

}

static ParametersServerPC& ParametersServerPC::GetInstance() {

    static ParametersServerPC instance;
    return instance;

}

virtual bool ParametersServerPC::Load() {

    return true; // TODO

}

my_test_file.cpp

#include "mid_level/parameters_server_pc.hpp"

ParametersServerPC& paramServer = ParametersServerPC::GetInstance();

3 个答案:

答案 0 :(得分:1)

这是一种可接受的模式。这是一个证明可行性的MVCE:

#include <iostream>
#include <string>

using namespace std;

class A {
public:
    int ival;
    string strval;

    static A& getInstance();
private:
    A(int ival, string strval): ival(ival), strval(strval) {}
    A(A& src): ival(src.ival), strval(src.strval) {}
    ~A() {};
};

A& A::getInstance() {
    static A instance(1, "foo");

    return instance;
}



int main() {
    A& a = A::getInstance();
    cout << a.ival << endl;

    // A a1 = A::getInstance(); error
    // A a2 = a; error
    // A a3(2, "bar"); error

    return 0;
}

答案 1 :(得分:1)

首先,标记您的~ParametersServerABS();析构函数virtual,以便能够正确删除对象。其次,您需要从 parameters_server_pc.cpp 文件中删除virtualstatic个关键字:它们仅用于定义(针对您的头文件)。

接下来,做对了:

class ParametersServerPC {
    // your code

    private:
        ParametersServerPC(std::string parameterFileName = "parameters.txt");
        ParametersServerPC(ParametersServerPC const&) = delete;
        void operator=(ParametersServerPC const&) = delete;
};

Singleton意味着您无法获取对象的副本:您需要禁止使用复制构造函数和复制赋值运算符。 无论如何,我认为您的问题出现在 parameters_server_pc.cpp 文件的static中。将其从实现部分(cpp文件)中删除以解决问题,但将其保留在定义部分(头文件)中。

答案 2 :(得分:1)

  

未定义对`ParametersServerPC :: GetInstance()'

的引用

这似乎是链接器错误。如果你可以发布编译控制台的输出,我们可能会进一步缩小它。

与此同时,您可以检查构建系统,看看是否从编译中省略了一些源文件。

在单身人士模式上已有一些好的答案。有关in a description of the patternin a general question about singletons主题的更多信息。