Say I have this code:
#include <iostream>
using namespace std;
class Something
{
int field1;
static Something *nill;
static bool initialized;
static void initialize() {
if (initialized)
return;
initialized = true;
}
public:
static Something* Nill()
{
initialize();
return nill;
}
static Something* Singleton(int field1)
{
initialize();
Something *ret = new Something();
ret->field1 = field1;
return ret;
}
}
Something* Something::nill = new Something();
bool Something::initialized = false;
int main(void)
{
Something *smth = something->Nill();
return 0;
}
Why isn't 'Something' a Singleton Class, and how could I make it one? Also how could I split this code into 2 files a .h and a .cpp? I had problems with that because I have some global variables here and I don't know how to use them in other files..
This is not a singleton class. Singleton class implies that in any given time you cannot have more than 1 instance of the class. In your example, you're not only creating a new instance but even return new class objects in its methods.
Make a default constructor protected (copy or move constructors too if you really want to be sure it's as singleton). Then use your static 'nill' as shown below:
class Something {
protected:
Something() = default;
...
int main() {
Something::nill->Nill();
...
P.s. Are you sure you need a singleton? Your methods say opposite.
Related
I am trying to implement a pattern in C++ where a nested private class inherits from the outer class and the private class is instantiated via a static factory method in the outer abstract class.
I have this code now, that compiles, but I am not sure whether I did it correctly.
Search.h:
namespace ns_4thex {
class Search {
private:
class Implementation;
public:
static Search & create();
virtual int doIt() = 0;
};
class Search::Implementation: public Search {
int doIt();
};
}
Search.cpp:
#include "Search.h"
using namespace ns_4thex;
Search & Search::create() {
return *(new Search::Implementation());
}
int Search::Implementation::doIt() {
return 0;
}
Thought?
A static factory method always returns a pointer type. So the create function should return a pointer or smart pointers in modern c++.
The declaration:
static std::unique_ptr<Search> create();
The definition:
std::unique_ptr<Search> Search::create() {
return std::make_unique<Search::Implementation>();
}
The complete code may like this:
#include <memory>
namespace ns_4thex {
class Search {
private:
class Implementation;
public:
static std::unique_ptr<Search> create();
virtual int doIt() = 0;
};
class Search::Implementation : public Search {
int doIt();
};
std::unique_ptr<Search> Search::create() {
return std::make_unique<Search::Implementation>();
}
int Search::Implementation::doIt() { return 0; }
} // namespace ns_4thex
Your example has potentially a memory leak. The factory pattern should return a pointer type instead of the reference type. The caller using it can free the allocated memory
Search* Search::create() {
return new Search::Implementation();
}
I wish to create a static Class object which should stay in the memory while the program is running. The object needs to be initialized only once by the init function and the output function will be called in a static method always. Does my code make sense and is it thread-safe?
class Singleton
{
public:
static void init(const int value)
{
static Singleton inst;
inst.Value = value;
}
static int prnValue()
{
return Value;
}
private:
Singleton() {};
static int Value;
};
int main()
{
int inputValue = 10;
Singleton::init(inputValue);
cout << Singleton::prnValue();
return 0;
}
New Edit:
Or can I try like this then?
class Singleton
{
public:
static Singleton& init(const int value)
{
static Singleton inst;
inst.Value = value;
return inst;
}
static int prnValue()
{
return Value;
}
private:
Singleton() {};
static int Value;
};
Addition:
Meyer's singleton example look like
class Singleton
{
public:
static Singleton& init()
{
static Singleton inst;
return inst;
}
private:
Singleton() {};
};
So Isn't my code consistent with Meyer's example?
Try4:
How about this?
class Singleton
{
public:
static Singleton& init(int value)
{
static Singleton inst(value);
return inst;
}
static int prnValue()
{
return Value;
}
private:
Singleton(value)
{
Value = value;
}
int Value;
};
Added comment:
How to pass argument in a singleton
seems to provide the same answer as Try4.
Abandon Singleton and make Value a const global variable initialized with a helper function.
Example:
// anonymous namespace to bind the global to this file to prevent the static
// initialization order fiasco
namespace
{
const int Value = ReadIniFile("section", "key", default_value);
}
But what if you need to use this variable in other files? The best advice I've got is don't. But if you must, the static initialization order fiasco needs to be overcome. Here's a quick way to do that that is similar to what you've seen so far:
// Lazy loader function similar to Meyers Singleton
int Value()
{
static int value = ReadIniFile("section", "key", default_value);
return value;
}
Usage:
me_function_need_Value(Value());
This ensures that Value is initialized before anyone can try to use it no matter which file in your project needs it. Unfortunately it's now hard to figure out when it goes out of scope, so the problem doesn't really go away. It's just moved from the start of the program to the end where it is a little more manageable. See Destruction order of static objects in C++ .
Ensure no one uses Value after main exits and you'll be safe. Still, use with caution.
Is there any difference or specific advice when it comes to the following approaches for defining singletons?
In 1, the singleton object is a class private static, but in 2, it's a file static.
Note: m_initedObj1 is just there to show that class has state, and use case is to call this singleton->DoSomething() many times, without needing to init this object again.
1)
// header file
class Foo {
private:
static Foo* s_fooSingleton;
Foo();
Obj1 m_initedObj1;
public:
static Foo* Singleton();
static void ClearSingleton();
Bar DoSomething(...);
};
// cpp file
Foo* Foo::s_fooSingleton = nullptr;
Foo::Foo() { m_initedObj1 = InitObj1Somewhere(); }
/*static*/ Foo* Foo::Singleton()
{
if(!Foo::s_fooSingleton)
Foo::s_fooSingleton = new Foo();
return Foo::s_fooSingleton;
}
/*static*/ void Foo::ClearSingleton()
{
if(Foo::s_fooSingleton)
delete Foo::s_fooSingleton;
Foo::s_fooSingleton = nullptr;
}
Bar Foo::DoSomething(...) { // do something }
2)
// header file
class Foo {
private:
Foo();
Obj1 m_initedObj1;
public:
static Foo* Singleton();
static void ClearSingleton();
Bar DoSomething(...);
};
// cpp file
static Foo* s_fooSingleton = nullptr;
Foo::Foo() { m_initedObj1 = InitObj1Somewhere(); }
/*static*/ Foo* Foo::Singleton()
{
if(!s_fooSingleton)
s_fooSingleton = new Foo();
return s_fooSingleton;
}
/*static*/ void Foo::ClearSingleton()
{
if(s_fooSingleton)
delete s_fooSingleton;
s_fooSingleton = nullptr;
}
Bar Foo::DoSomething(...) { // do something }
As JerryGoyal states in the comments, in 2) other methods in the same .cpp file can modify s_fooSingleton.
On the other hand, they are not both thread-safe. If you don't really mind the clearing (calling ClearSingleton() explicitly), just go with the Scott Meyers' version. Otherwise, go with the double checked locking version.
It's really hard to ensure the safety in case of explicitly deleting. You always have to check whether it's deleted before you access it. If it's a multi-threaded executable, checking and using it must be atomic, because it can be deleted just after checking.
Double checked locking could be used to create and delete the singleton, which ensures you that there is only one instance at a time. Yet, it does not ensure the object really exist, since you may accidentally delete it.
You may use smart pointers to count references and delete it if no references exist.
Or even better, see this answer https://stackoverflow.com/a/15733545/1632887.
I just wouldn't delete it explicitly if I were you!
Maybe this will satisfy you more:
class MyClass1 {
private:
MyClass1(){}
public:
MyClass1& Instance() {
static MyClass1 theSingleInstance;
return theSingleInstance;
}
};
class MyClass2 {
private:
MyClass2() {}
public:
MyClass2* Instance() {
static MyClass2* theSingleInstance = new MyClass2;
return theSingleInstance;
}
};
class MyClass3 {
private:
MyClass3() {}
public:
MyClass3* Instance() {
static MyClass3 theSingleInstance;
return &theSingleInstance;
}
};
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.
I need several C++ classes to have a static method "register", however the implementation of register varies between those classes.
It should be static because my idea is to "register" all those classes with Lua (only once of course).
Obviously I can't declare an interface with a static pure virtual function. What do you guys suggest me to do ? Simplicity is welcome, but I think some kind of template could work.
Example of what I would like to achieve
class registerInterface
{
public:
static virtual void register() = 0; //obviously illegal
};
class someClass: public registerInterface
{
static virtual void register()
{
//I register myself with Lua
}
}
class someOtherClass: public registerInterface
{
static virtual void register()
{
//I register myself with Lua in a different way
}
}
int main()
{
someClass::register();
someOtherClass::register();
return 0;
}
Based on how you've described the problem, it's unclear to me why you even need the 'virtual static method' on the classes. This should be perfectly legal.
class SomeClass {
static void register(void) {
...
}
}
class SomeOtherClass {
static void register(void) {
...
}
}
int main(int argc, char* argv[]) {
SomeClass::register();
SomeOtherClass::register();
return 0;
}
Drop the RegisterInterface, I don't think you need it.
If it helps, you could take Hitesh's answer, and add:
struct luaRegisterManager {
template <typename T>
void registrate() {
T::registrate();
// do something else to record the fact that we've registered -
// perhaps "registrate" should be returning some object to help with that
}
};
Then:
int main() {
luaRegisterManager lrm;
lrm.registrate<someClass>();
lrm.registrate<someOtherClass>();
}
More generally, if you want to introduce any dynamic polymorphism in C++, then you need an object, not just a class. So again, perhaps the various register functions should be returning objects, with some common interface base class registeredClass, or classRegistrationInfo, or something along those lines.
Could provide an example of what you feel it is that you need dynamic polymorphism for? Hitesh's code precisely matches your one example, as far as I can see, so that example must not cover all of your anticipated use cases. If you write the code that would be using it, perhaps it will become clear to you how to implement it, or perhaps someone can advise.
Something else that might help:
#include <iostream>
#include <string>
#include <vector>
struct Registered {
virtual std::string name() = 0;
virtual ~Registered() {}
Registered() {
all.push_back(this);
}
static std::vector<Registered*> all;
};
std::vector<Registered*> Registered::all;
typedef std::vector<Registered*>::iterator Iter;
template <typename T>
struct RegisteredT : Registered {
std::string n;
RegisteredT(const std::string &name) : n(name) { T::registrate(); }
std::string name() { return n; }
// other functions here could be implemented in terms of calls to static
// functions of T.
};
struct someClass {
static Registered *r;
static void registrate() { std::cout << "registering someClass\n"; }
};
Registered *someClass::r = new RegisteredT<someClass>("someClass");
struct someOtherClass {
static Registered *r;
static void registrate() { std::cout << "registering someOtherClass\n"; }
};
Registered *someOtherClass::r = new RegisteredT<someOtherClass>("someOtherClass");
int main() {
for (Iter it = Registered::all.begin(); it < Registered::all.end(); ++it) {
std::cout << (*it)->name() << "\n";
}
}
There are all sorts of problems with this code if you try to split it across multiple compilation units. Furthermore, this kind of thing leads to spurious reports from memory leak detectors unless you also write some code to tear everything down at the end, or use a vector of shared_ptr, Boost pointer vector, etc. But you see the general idea that a class can "register itself", and that you need an object to make virtual calls.
In C++ you usually try to avoid static initialisation, though, in favour of some sort of setup / dependency injection at the start of your program. So normally you would just list all the classes you care about (calling a function on each one) rather than try to do this automatically.
Your intentions are noble, but your solution is inkling towards "overengineering" (unless I am missing an obvious solution).
Here is one possibility: You can use the Virtual Friend function idiom For example,
class RegisterInterface{
friend void register(RegisterInterface* x){x->do_real_register();}
protected:
virtual void do_real_register();
}
class Foo : public RegisterInterface{
protected:
virtual void do_real_register(){}
};
class Bar : public RegisterInterface{
protected:
virtual void do_real_register(){}
};
int main(int argc, char* argv[]) {
BOOST_FOREACH(RegisterInterface* ri, registered_interfaces)
{
register(ri);
}
return 0;
}
I know you've already accepted an answer, but I figured I would write this up anyway. You can have self-registering classes if you use some static initialization and the CRTP:
#include <vector>
#include <iostream>
using namespace std;
class RegisterableRoot // Holds the list of functions to call, doesn't actually need
// need to be a class, could just be a collection of globals
{
public:
typedef void (*registration_func)();
protected:
static std::vector<registration_func> s_registery;
public:
static void do_registration()
{
for(int i = 0; i < s_registery.size(); ++i)
s_registery[i]();
}
static bool add_func(registration_func func) // returns something so we can use it in
// in an initializer
{
s_registery.push_back(func);
return true;
}
};
template<typename RegisterableType> // Doesn't really need to inherit from
class Registerable : public RegisterableRoot // RegisterableRoot
{
protected:
static const bool s_effect;
};
class A : public Registerable<A> // Honestly, neither does A need to inherit from
// Registerable<T>
{
public:
static void Register()
{
cout << "A" << endl;
}
};
class B : public Registerable<B>
{
public:
static void Register()
{
cout << "B" << endl;
}
};
int main()
{
RegisterableRoot::do_registration();
return 0;
}
std::vector<RegisterableRoot::registration_func> RegisterableRoot::s_registery;
template <typename RegisterableType> // This is the "cute" part, we initialize the
// static s_effect so we build the list "magically"
const bool Registerable<RegisterableType>::s_effect = add_func(&RegisterableType::Register);
template class Registerable<A>; // Explicitly instantiate the template
// causes the equivalent of
// s_registery.push_back(&A::Register) to
// be executed
template class Registerable<B>;
This outputs
A
B
although I wouldn't rely on this order if I were you. Note that the template class Registerable<X> need not be in the same translation unit as the call to do_registration, you can put it with the rest of your definition of Foo. If you inherit from Registerable<> and you don't write a static void Register() function for your class you'll get a (admittedly probably cryptic) compiler error much like you might expect if there really was such a thing as "static virtuals". The "magic" merely adds the class specific function to the list to be called, this avoids several of the pitfalls of doing the actual registration in a static initializer. You still have to call do_registration for anything to happen.
How about this way? Define an interface class:
// IFoobar.h
class IFoobar{
public:
virtual void Register(void) = 0;
}
Then define the class that handles the register..
// RegisterFoobar.h
class RegisterFoobar{
public:
// Constructors etc...
IFoobar* fooBar;
static void RegisterFoobar(IFoobar& fubar){
foobar = &fubar;
}
private:
void Raise(void){ foobar->Register(); }
}
Now, then define another class like this
// MyFuBar.h
class MyFuBar : IFoobar{
public:
// Constructors etc...
void Register(void);
private:
RegisterFoobar* _regFoobar;
}
Call the code like this:
//MyFuBar.cpp
MyFuBar::MyFuBar(){
_regFoobar = new Foobar();
_regFoobar->RegisterFoobar(this);
}
void MyFuBar::Register(void){
// Raised here...
}
Maybe I have misunderstood your requirements...