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();
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.
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;
}
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).
Related
Background
I have been learning how to implement the pimpl idiom using the newer c++11 method described by Herb Sutter at this page: https://herbsutter.com/gotw/_100/
I'm trying to modify this example by adding a member variable to the private implementation, specifically a std::string (although a char* has the same issue).
Problem
This seems to be impossible due to the use of a static const non-integral type. In-class initialization can only be done for integral types, but because it is static it can't be initialized in the constructor either.
A solution to this problem is to declare the private variable in the header file, and initialize it in the implementation, as shown here:
C++ static constant string (class member)
However, this solution does not work for me because it breaks the encapsulation I'm trying to achieve through the pimpl idiom.
Question
How can I hide a non-integral static const variable within the hidden inner class when using the pimpl idiom?
Example
Here is the simplest (incorrect) example I could come up with demonstrating the problem:
Widget.h:
#ifndef WIDGET_H_
#define WIDGET_H_
#include <memory>
class Widget {
public:
Widget();
~Widget();
private:
class Impl;
std::unique_ptr<Impl> pimpl;
};
#endif
Widget.cpp:
#include "Widget.h"
#include <string>
class Widget::Impl {
public:
static const std::string TEST = "test";
Impl() { };
~Impl() { };
};
Widget::Widget() : pimpl(new Impl()) { }
Widget::~Widget() { }
Compilation command:
g++ -std=c++11 -Wall -c -o Widget.o ./Widget.cpp
Note that this example fails to compile because the variable TEST cannot be assigned at declaration due to it not being an integral type; however, because it is static this is required. This seems to imply that it cannot be done.
I've been searching for previous questions/answers to this all afternoon, but could not find any that propose a solution that preserves the information-hiding property of the pimpl idiom.
Solution Observations:
In my example above, I was attempting to assign the value of TEST in the Impl class declaration, which is inside of Widget.cpp rather than its own header file. The definition of Impl is also contained within Widget.cpp, and I believe this was the source of my confusion.
By simply moving the assignment of TEST outside of the Impl declaration (but still within the Widget/Impl definition), the problem appears to be solved.
In both of the example solutions below, TEST can be accessed from within Widget by using
pimpl->TEST
Attempting to assign a different string into TEST, i.e.
pimpl->TEST = "changed"
results in a compiler error (as it should). Also, attempting to access pimpl->TEST from outside of Widget also results in a compiler error because pimpl is declared private to Widget.
So now TEST is a constant string which can only be accessed by a Widget, is not named in the public header, and a single copy is shared among all instances of Widget, exactly as desired.
Solution Example (char *):
In the case of using a char *, note the addition of another const keyword; this was necessary to prevent changing TEST to point to another string literal.
Widget.cpp:
#include "Widget.h"
#include <stdio.h>
class Widget::Impl {
public:
static const char *const TEST;
Impl() { };
~Impl() { };
};
const char *const (Widget::Impl::TEST) = "test";
Widget::Widget() : pimpl(new Widget::Impl()) { }
Widget::~Widget() { }
Solution Example (string):
Widget.cpp:
#include "Widget.h"
#include <string>
class Widget::Impl {
public:
static const std::string TEST;
Impl() { };
~Impl() { };
};
const std::string Widget::Impl::TEST = "test";
Widget::Widget() : pimpl(new Widget::Impl()) { }
Widget::~Widget() { }
Update:
I realize now that the solution to this problem is completely unrelated to the pimpl idiom, and is just the standard C++ way of defining static constants. I've been used to other languages like Java where constants have to be defined the moment they are declared, so my inexperience with C++ prevented me from realizing this initially. I hope this avoids any confusion on the two topics.
#include <memory>
class Widget {
public:
Widget();
~Widget();
private:
class Impl;
std::unique_ptr<Impl> pimpl;
};
/*** cpp ***/
#include <string>
class Widget::Impl {
public:
static const std::string TEST;
Impl() { };
~Impl() { };
};
const std::string Widget::Impl::TEST = "test";
Widget::Widget() : pimpl(new Impl()) { }
Widget::~Widget() { }
You might want to consider making TEST a static function which returns a const std::string&. This will allow you to defined it inline.
You could also replace const by constexpr in your example and it will compile.
class Widget::Impl {
public:
static constexpr std::string TEST = "test"; // constexpr here
Impl() { };
~Impl() { };
};
Update:
Well, it seems that I was wrong... I always store raw string when I want constants.
class Widget::Impl {
public:
static constexpr char * const TEST = "test";
};
Depending on the usage pattern, it might be appropriate or not. If not, then define the variable as explained in the other answer.
I have a weird question. It is so weird it is probably quite easy to solve.
I created a software and I need to implement a class Sing with an sing objeect that must be reached from all classes from the software. Therefore I created it as singleton object in the main function.
My problem is, how can the object sing be reached from other classes (like ClassA) without creating pointers which are handovered by a pointer to every single class in the code.
All the class definition is located in the sing.h file. If I put the definition into the sing.cpp file the compiler will fail.
I managed to create this sing object, but it is not visible from ClassA. How can the object sing be seen without handing over pointers to the constructors of each class?
sing.h file:
#ifndef _SING_H_
#define _SING_H_
//declaration
class Singleton
{
public:
static Singleton* Instance();
static Singleton* InstanceSlave();
int a;
int setTest(int);
protected:
Singleton(){}
private:
static Singleton* _instance;
static Singleton* _instanceSlave;
};
//definitions (only work in header file, not in .cpp file
Singleton* Singleton::_instance =0;
Singleton* Singleton::Instance()
{
if (_instance == 0 )
{
_instance = new Singleton;
}
return _instance;
}
int Singleton::setTest(int b)
{
return 1;
}
#endif _CONF_H_
main.cpp file:
int main()
{
Singleton* sing = sing->Instance();
sing->setTest(2);
ClassA* classa = new ClassA();
}
main.h file:
#inlucde <iostream>
#include "sing.h"
#include "classA.h"
inside the ClassA I would like to have something like this:
classA.h
#inlude sing.h
class classA
{
public:
void doSomeThing(int);
}
classA.cpp:
#include ClassA.h
{
void ClassA::doSomeThing(int a)
{
sing.setTest(a);
}
}
My problem is, how can the object sing be reached from other classes (like ClassA) without creating pointers which are handovered by a pointer to every single class in the code.
The canonical way is to use Scott Meyer's Singleton and provide a static function like
static Singleton& Instance() {
static Singleton theInstance;
return theInstance;
}
Usage is
Singleton::Instance().setTest(2);
In general the Singleton Pattern isn't really considered a good technique, because the coupling with the rest of the code is too tight. It's better to use interfaces (abstract classes) and pass these around as necessary.
Just use
Singleton::Instance()->setTest(a);
A C++ n00b question. Is it possible to call a private constructor from a static method defined in the cpp? I'd like to keep methods out of the header file if possible -- I figure there should be a way to do this. I'm getting an error when attempting this:
"cannot access private member declared in class SomeClass"
/////////////////
// SomeClass.h //
/////////////////
class SomeClass {
public:
static SomeClass SomeMethod();
private:
SomeClass(int i);
}
///////////////////
// SomeClass.cpp //
///////////////////
static SomeClass OSImplementation() {
return SomeClass(0);
};
// calls implementation
SomeClass SomeClass::SomeMethod() {
return OSImplementation();
}
You can make OSImplementation a friend method.
Or you can make OSImplementation a static method within the class (but that has to be declared in the header).
Or, probably the most common way to do this, is to have an internal implementation class, like this:
class SomeClass {
public:
//...
private:
struct Impl;
Impl* intern;
};
In your cpp file, you declare struct SomeClass::Impl.
In your constructor, create the SomeClass::Impl instance. Delete it in the destructor. And implement the copy-constructor and the assignment operator!
This is called the PIMPL (pointer to implementation) idiom (Wikipedia, c2.com). It's used a lot in big projects like Qt.
Yes, it is possible, by making the OSImplementation() friend of SomeClass. Next example compiles without warnings and errors using g++ 4.6.1 :
#include <iostream>
// declare in hpp
class SomeClass {
friend SomeClass OSImplementation();
public:
static SomeClass SomeMethod();
void foo();
private:
SomeClass(int);
};
int main()
{
auto obj = SomeClass::SomeMethod();
obj.foo();
}
// define in cpp
SomeClass SomeClass::SomeMethod(){
return SomeClass( 5 );
}
SomeClass::SomeClass(int){
}
void SomeClass::foo(){
std::cout<<"foo"<<std::endl;
}
SomeClass OSImplementation()
{
return SomeClass::SomeMethod();
}
I am trying to implement the following class. However, when I try to instantiate an object of the class within its definition and pass "0" as value to initialize the object, i get an error:
"a type specifier is expected".
Can anyone explain how can i remove this error?
class MessageType
{
public:
static const MessageType msgEvent(0);
private:
MessageType();
virtual ~MessageType();
MessageType(int);
};
You need to initialize(define) it outside the class definition in a cpp file.
MessageType const MessageType::msgEvent;
However, Your intent in doing so is not very clear. Are you trying to implement a Singleton Pattern, probably this sample implementation might help, I leave it to you to decide, whether you really need a singleton, inspite of its disadvantages:
//MessageType.h
#include <boost/noncopyable.hpp>
class MessageType: private boost::noncopyable
{
public:
static MessageType* instance();
private:
MessageType();
~MessageType();
static bool g_initialised;
// static initialisation
static MessageType g_instance;
// dynamic initialisation
};
// MessageType.cpp
#include "MessageType.hpp"
#include <ostream>
#include <iostream>
#include <cstring>
bool MessageType::g_initialised;
// static initialisation
MessageType MessageType::g_instance;
// dynamic initialisation
MessageType::MessageType()
{
g_initialised = true;
}
MessageType::~MessageType()
{
g_initialised = false;
}
MessageType* MessageType::instance()
{
return g_initialised ? &g_instance : 0;
}
You can only initialize static member variables in the definition if they are of int type.
class MessageType
{
public:
static int sCount = 0; // That is fine.
static std::string sLogName; // That is fine.
static std::string sLogName("log.txt"); // Fail!
};
There's no way around this rule. If you want to initialize a static member variable, then you have to do it in the cpp:
std::string MessageType::sLogName("log.txt"); // fine, in the cpp.
This same rule applies directly to your MessageType instance, and has nothing to do with the fact that the class is of it's own type.
OK, I have been looking about but can not for the wits of me find a reason to why this should not work:
Base class (misc/interface/handler.h)
#ifndef __t__MISC_VIRTUAL_HANDLER_H
#define __t__MISC_VIRTUAL_HANDLER_H
#pragma message("Starting with 'handler.h'")
namespace t {
namespace misc {
namespace interface {
class Handler {
public:
Handler();
virtual ~Handler();
virtual int setup() = 0;
virtual int teardown() = 0;
virtual int update() = 0;
protected:
private:
};
}
}
}
#pragma message("Ending with 'handler.h'")
#endif // __t__MISC_VIRTUAL_HANDLER_H
Derived class (graphics/handler.h):
#ifndef __t_GRAPHICS_HANDLER_H
#define __t_GRAPHICS_HANDLER_H
#include "../misc/interface/handler.h"
namespace t {
namespace graphics {
class Handler: public t::misc::interface::Handler {
public:
Handler();
virtual ~Handler();
int getResolutionX() { return m_resolutionX; }
int getResolutionY() { return m_resolutionY; }
bool getFullscreen() { return m_isFullscreen; }
protected:
private:
unsigned int m_resolutionX, m_resolutionY;
bool m_isFullscreen;
}; // class Handler
} // namespace graphics
} // namespace t
#endif // __t_GRAPHICS_HANDLER_H
... which seems rather trivial.
Derived class implementation (graphics/handler.cpp):
#include "handler.h"
t::graphics::Handler::Handler(): t::misc::interface::Handler() {
}
t::graphics::Handler::~Handler() {
}
... which too is should be really trivial, but yields the error:
src\graphics\handler.cpp|5|undefined reference to `t::misc::interface::Handler::Handler()'
I'm using MinGW with Code Blocks and what ever standard settings CB uses, I've tried building the same situation with test classes and that works as intended, both in same environment and Linux with vanilla g++.
I can't see any implementation of t::misc::interface::Handler::Handler() in your code - and it is going to be called by the inheriting class's constructor, so it needs an implementation. The linker can't find it, so it complains.
Just change:
Handler();
virtual ~Handler();
in the abstract class to:
Handler() {}
virtual ~Handler() {}
and you're ready to go.
As an aside, identifiers starting with two underscores are illegal in C++ (since they are reserved for the compiler). In practice, they shouldn’t be a problem in preprocessor but it’s best to err on the safe side here: simply don’t use them.