I am trying to bind a shared library in Python using pybind11.
I created a simplified version, that illustrates the problem.
From python I call the function foobar.
This function calls a static function, that calls a factory, that again calls a factory, that constructs the Singleton.
This works fine when I run the code as a executable (without using the binder).
The problem is that when the library is used with the binder through Python, the Singleton gets constructed twice (e.i, with every use of the Singleton).
Once in the constructor of Factory2 and later in the foobar function.
I have already tried what other solutions here suggest by hiding the factories, but that didn't work or I might have implemented it wrong.
Any ideas on how this could be solved, so that the singleton only gets constructed once?
Any help would be greatly appreciated!
I created a small example that illustrates the problem.
Main.cpp:
int foobar(){
Singleton::createModel();
Singleton::getModel(); //SECOND CALL TO CONSTRUCTOR
return 0;
}
Singleton.h:
class Singleton {
public:
static void createModel(){
Factory factory;
}
static void setModel(Model *model) {
Singleton::getInstance().model = model;
}
static Model *getModel() {
return Singleton::getInstance().model;
}
private:
static Singleton &getInstance() {
static Singleton instance;
return instance;
}
Singleton() : model(nullptr) {};
~Singleton() {};
Model *model;
};
Factory.h:
class Factory {
public:
Factory(){
Factory2 factory2;
}
};
Factory2.h:
class Factory2 {
public:
Factory2();
};
Related
I am new to object oriented programming in C++, and well, it hasn't clicked with me yet, so this may sound like a too easy question. In my homework, I need to: Create a single instance of the class in function main().
What does my professor mean by that? When I tried searching for an answer, they were too specific to a problem, and I just want a general answer please
Sound like you just need something like:
class A {};
int main() {
A a; // creates instance of class A
return 0;
}
Below is my codeļ¼
Singleton.h
#ifndef __C__Review__Singleton__
#define __C__Review__Singleton__
#include <iostream>
class Singleton{
private:
Singleton() { }
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
static Singleton *instance;
public:
static Singleton *getInstance();
static void release();
};
#endif /* defined(__C__Review__Singleton__) */
Singleton.cpp
#include "Singleton.h"
Singleton *Singleton::instance = 0;
Singleton* Singleton::getInstance()
{
if(instance == nullptr)
instance = new Singleton();
return instance;
}
void Singleton::release()
{
if (instance != NULL) {
delete instance;
instance = NULL;
}
}
Classes are one of the main part of C++. Moreover, using OOPs concepts while creating and extending classes is also very powerful feature of cpp.
Classes contains properties and member functions. Both of these can be public, private or protected.
Private members of a class are accessible only from within other member functions of the same class.
Protected are similar to private but, they can be accessed by child classes also.
Public members, as the name suggests, can be accessed by objects(instance) of the class.
You can visualize class as a type and object as a variable if that type. Just for understanding.
Classes in C++ are created as follows.
class Circle {
int radius; // member variable/property
public: // type of function()
void set_values (int,int);
int area() {return 3.14*radius*radius;}
};
Creating an object/instance of class means you are creating a variable of type class.
Objects can simply be crated as follows:
Circle c; // Stack based object
static Circle t1; // Static object
Here, keyword static is used to create a singleton instance/object of that class.
For further information, just google it. May be basic knowledge of C++ is required, can be obtained from this,this or this links.
I'm currently porting my project from Windows to Linux.
The project consists of a 'main' shared library, several plugins (also shared libraries) and a launcher application.
Within the 'main' shared library there's a template singleton class another class can inherit from to use the singleton pattern.
The template singleton class is implemented as follows:
template<class T>
class Singleton
{
public:
static T* getInstance()
{
if(!m_Instance)
{
m_Instance = new T();
}
return m_Instance;
}
private:
static T* m_Instance;
protected:
Singleton()
{
assert(!m_Instance);
m_Instance = (T*)this;
}
~Singleton()
{
m_Instance = 0;
}
};
template<class T> T* Singleton<T>::m_Instance = 0;
A class that inherits from the Singleton class is - for example - the Logger class.
So whenever I call
Logger::getInstance()
I get a valid instance of the logger class.
For windows this works across multiple DLLs.
If I instantiate the logger in the 'main' dll and try to get the instance in plugin A and B, it'll always return the same instance.
On Linux however I can not reproduce this behavior. For both plugin A and B the assert
assert(!m_Instance);
triggers and the program stops.
What do I have to do to get the same behavior as I have in Windows with dlls?
I tried linking with -rdynamic but unfortunately this didn't solve the problem.
IMHO the closest thing you can get that suffices your requirements is something using the following pattern:
#include <iostream>
template<class Derived>
class Singleton {
public:
static Derived& instance() {
static Derived theInstance;
return theInstance;
}
protected:
Singleton() {}
private:
Singleton(const Singleton<Derived>&);
Singleton<Derived>& operator=(const Singleton<Derived>&);
};
class ASingleton : public Singleton<ASingleton> {
public:
void foo() { std::cout << "foo() called ..." << std::endl; }
};
int main() {
ASingleton& a = ASingleton::instance();
a.foo();
return 0;
}
Whatever you want to be accessible through an interface might be injected using multiple inheritance. Though the benefit of using a Singleton<Derived> base class is a bit questionable, it just provides that narrow instance() implementation.
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
The following code is my implementation of the Singleton Pattern.
#include <iostream>
template<class T>
class Uncopyable
{
protected:
Uncopyable(){}
~Uncopyable(){}
private:
Uncopyable(const Uncopyable<T>&);
Uncopyable& operator=(const Uncopyable<T>&);
};
template <class T>
class Singleton : private Uncopyable<T>
{
public:
static T* getInstancePtr()
{
return instance;
}
protected:
Singleton<T>()
{
if(instance == 0)
{
instance = new T();
}
};
~Singleton<T>()
{
};
private:
static T* instance;
};
template<class T> T* Singleton<T>::instance = 0;
class Test : public Singleton<Test>
{
public:
Test(){};
~Test(){};
inline void test() const
{
std::cout << "Blah" << std::endl;
}
private:
friend class Singleton<Test>;
protected:
};
int main(int argc, char* argv[])
{
Test* t = Test::getInstancePtr();
Test* t2 = Test::getInstancePtr();
t->test();
t2->test();
return 0;
}
It works in this form, however I am uncertain as to whether it really is correct due to the constructor and destructor of the Singleton being protected as opposed to being private. If I declare them as private the code will not compile as they are not accessible to the class. Is this implementation safe to use, or is there anything I can do to improve it to ensure only one instance will be created and used.
Thanks
That is most certainly an incorrect implementation of singleton. There are too many issues with that implementation.
In C++11, you can make use of std::call_once and std::once_flag to implement singleton pattern. Here is one example:
//CRTP base singleton class
template<typename TDerived>
class Singleton
{
static std::unique_ptr<TDerived> m_instance;
static std::once_flag m_once;
protected:
Singleton() {}
public:
~Singleton() { }
static TDerived & GetInstance()
{
std::call_once
(
Singleton::m_once,
[] (){ Singleton::m_instance.reset( new TDerived() ); }
);
return *m_instance;
}
};
template<typename TDerived>
std::unique_ptr<TDerived> Singleton<TDerived>::m_instance;
template<typename TDerived>
std::once_flag Singleton<TDerived>::m_once;
Now you can derive from it as:
class Demo : public Singleton<Demo>
{
public:
void HelloWorld() { std::cout << "HelloWorld" << std::endl; }
};
//call HelloWorld() function through singleton instance!
DemoSingleton::GetInstance().HelloWorld();
There are several things wrong with the code you've posted.
The Uncopyable class doesn't need to be templated
The Singleton class isn't thread safe
Your Singleton instance is never deleted
I would re-implement your accessor as:
static T& GetInstance()
{
static T instance;
return instance;
}
Then make sure you call Singleton<T>::GetInstance() in the main thread of your application (during initialisation) to avoid any threading issues.
your destructor private will cause the compile error?cause when the process ends,the compile cannot call the private function so the object cannot be delete
No this is not a good implementation of the singleton pattern, it does not work!
The only instance of Test in the example is NULL! The constructor is never called!
You need to change Singleton::getInstancePtr to:
public:
static T* getInstancePtr()
{
if(instance == 0)
{
instance = new T();
}
return instance;
}
protected:
Singleton<T>() {};
The constructor for Test will now be called.
Usually singleton objects live for the lifetime of the program, so I do not implement them like that, because you use dynamic allocation, then someone must free it and you return a pointer to your singleton object, then you may accidentally delete it, so I will use something like this:
template< class T >
struct Singleton : Uncopyable<T> {
public:
static T& get_instance() {
static T res;
use( res ); // make sure object initialized before used
return res;
}
private:
static void use( T& ) {}
};
There is no correct implementation of the Singleton anti-pattern in C++.
The main issues with this attempt are:
The semantics are a very weird and error-prone; you must instantiate Singleton somewhere in order to create the instance. You example never creates the instance, and t->test() is erroneously calling a function via a null pointer.
Construction is not thread-safe; two instances could be created if two unsynchronised threads both instantiate Singleton.
If the instance is actually created, then it is leaked.
A less erroneous implementation might be more like this:
template <typename T>
T & singleton()
{
static T instance;
return instance;
}
but this still has issues: in particular, the instance may be destroyed before other static objects, which may attempt to access it in their destructors.
in C# you have to declare everything in a class so an example factory pattern could look like:
namespace MySpace {
public class CFactory
{
public static CFactory Current()
{
static CFactory singleton;
return singleton;
}
public CBase Create() { return null; }
}
}
in C++ you dont have this limitation.. So is it considered "bad practice" to have "factory" methods be global functions vs having them be a class?
example 1:
namespace MySpace {
// factory method
std::shared_ptr<CBase> CreateBase() { return NULL; }
}
example 2:
namespace MySpace {
// factory class
class CFactory
{
public:
std::shared_ptr<CBase> CreateBase() { return NULL; }
};
// factory method exposing class
CFactory& GetFactory()
{
static CFactory singleton;
return singleton;
}
}
example 3:
namespace MySpace {
// factory class with no global function
class CFactory
{
public:
std::shared_ptr<CBase> CreateBase() { return NULL; }
public:
static CFactory& getFactory()
{
static CFactory singleton;
return singleton;
}
};
}
the std library uses a lot of global functions for "factory methods".. an example of this would be std::make_shared.
I have used both before and I am just not sure if one is considered "better" over the other
You can presume from its usage in the standard library that a namespaced global factory is not implicitly wrong. Nothing prevents it from being correct.
Your approach of wrapping the factory in a class is an organizational change. Organization itself is neither good nor bad. It can be done well or poorly.
You should be fine doing whichever approach feels comfortable for its context. I have also seen both approaches used many times and neither were particularly problematic.
I still recommend putting the functions into a class (and even make them virtual). It's very nice to be able to replace your factory for any number of reasons, and doing things that way will make this much easier.
In the standard library the factory functions largely exist because function template expansion can be based on the types of the arguments, but until C++17 you couldn't have template classes that create instances of the class based on the types fed to the constructor. So those factory functions are more properly thought of as non-member constructors than a factory. They always return an instance of a particular type for example.
In a 'true' factory, the factory can return any type that implements the specified interface or is derived from the specified type. True factories always return pointers or (in rare instances) references, but not actual instances.
Here is an example of a way to implement singleton in c++
This way you can avoid global.
Hope this helps.
/* header file */
#ifndef EXAMPLE_H
#define EXAMPLE_H
class example
{
private:
example(); // constructor
public:
~example(); // destructor
static example *getExampleObject();
}
#endif
/* cpp file */
#include "example.h"
example *example::getExampleObject()
{
static example *theInstance = NULL;
if(theInstance == NULL)
{
theInstance = new example();
}
return theInstance;
}
Free functions are fine in C++ and I would go with that route.
Somewhat unrelated: why are you returning a shared smart pointer from a factory? Is the ownership of the newly created object always going to be shared?
I am trying to create a static member function that returns a pointer to one instance of the class. Is this possible in C++?
class DynamicMemoryLog
{
// Singleton Class:
public:
static DynamicMemoryLog* CreateLog();
void AddIObject( IUnknown* obj );
void ReleaseDynamicMemory();
private:
// static DynamicMemoryLog* instance;
static bool isAlive; // used to determine is an instance of DynamicMemoryLog already exists
DynamicMemoryLog();
~DynamicMemoryLog();
std::vector <IUnknown*> iObjectList;
};
This function below should create a new instance of the class & return a pointer to that object, but the compiler will not allow me to define a static function of the class if it returns a pointer(I think thats why it wont compile?):
static DynamicMemoryLog* DynamicMemoryLog :: CreateLog()
{
// Post:
if ( !isAlive ) // ( instance == NULL; )
{
DynamicMemoryLog* instance = new DynamicMemoryLog();
return instance;
}
return NULL;
}
The particular error you're getting is that when implementing a static member function, you don't repeat the static keyword. Fixing this should resolve the error.
Independently, there's something a bit odd with your code. You claim that this object is a singleton, but each call to CreateLog will create a new instance of the class. Do you really want this behavior, or do you want there to be many copies? I'd suggest looking into this before proceeding.
Here's the simplest solution, but not thread-safe. For analysis in detail, have a look at this article.
class DynamicMemoryLog
{
public:
static DynamicMemoryLog* GetInstance();
private:
DynamicMemoryLog();
static DynamicMemoryLog* m_pInstance;
}
DynamicMemoryLog* DynamicMemoryLog::GetInstance()
{
if(!m_pInstance)
{
m_pInstance = new DynamicMemoryLog();
}
return m_pInstance;
}
I usually do something like this:
class Singleton
{
public:
static Singleton* get()
{
static Singleton instance;
return &instance;
}
};
This way you won't have any nasty memory management issues.