Reputation: 1808
I am trying to implement a singleton design pattern without memory allocation. I tried searching for a solution but it seems like every solution was for a singleton defined with memory allocation.
I made the constructor private and the only code I added to the header file to make this a singleton design pattern was:
static ParametersServerPC& ParametersServerPC::GetInstance() {
static ParametersServerPC instance;
return instance;
}
This is a derived class from the base class ParametersServerABS
which has an empty constructor definition. ParametersServerABS
is an abstract class.
When I try to instantiate a ParametersServerPC
class in a separate file:
ParametersServerPC& paramServer = ParametersServerPC::GetInstance();
I get this error:
undefined reference to `ParametersServerPC::GetInstance()'
Here are the .cpp
and .hpp
files:
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();
Upvotes: 0
Views: 2708
Reputation: 343
undefined reference to `ParametersServerPC::GetInstance()'
This seems to be a linker error. If you can post the output of the compilation console we might narrow this down further.
In the meantime you could check your build system and see if you omitted some source files from compilation.
On the singleton pattern there are already some good answers. More on the topic in a description of the pattern and in a general question about singletons.
Upvotes: 1
Reputation: 16765
First, mark your ~ParametersServerABS();
destructor virtual
to be able to delete objects properly. Second, you need to remove virtual
and static
keywords from parameters_server_pc.cpp file: they are only for definitions (for your header file).
Next, do it right:
class ParametersServerPC {
// your code
private:
ParametersServerPC(std::string parameterFileName = "parameters.txt");
ParametersServerPC(ParametersServerPC const&) = delete;
void operator=(ParametersServerPC const&) = delete;
};
Singleton means that you can't get copies of an object: you need to forbid using of copy constructor and copy assignment operator.
And anyway I think your problem is in static
in your parameters_server_pc.cpp file. Remove it from implementation part (cpp file) in order to fix the problem but LEAVE it in the definition part (header file).
Upvotes: 1
Reputation: 149175
It is an acceptable pattern. Here is a MVCE demonstrating the feasability :
#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;
}
Upvotes: 1