I want to create a singleton class such that when all pointers to the class go away the destructor is called.
#include <memory>
#include <iostream>
class MyClass {
public:
uint8_t str[50]; //some random data
MyClass() {LOG("constructor Called"); }
~MyClass() {LOG("destructor Called");}
static std::shared_ptr<MyClass> &Get();
private:
static std::shared_ptr<MyClass> instance;
};
std::shared_ptr<MyClass> MyClass::instance=NULL;
std::shared_ptr<MyClass> &MyClass::Get()
{
if (instance == NULL)
{
instance= std::shared_ptr<MyClass>(new MyClass());
return instance;
}
return instance;
}
int main()
{
std::shared_ptr<MyClass> &p1 =MyClass::Get();
printf("We have %" PRIu32, p1.use_count());
if (1)
{
std::shared_ptr<MyClass> &p2 =MyClass::Get();//this should not
// create a new class
printf("We have %" PRIu32, p1.use_count()); //this should be two...
printf("We have %" PRIu32, p2.use_count()); //this should be two...
//when p1 goes out of scope here it should not call destructor
}
printf("We have %" PRIu32, p1.use_count());
//now destructor should be called
return 0;
}
The above code does not work as the static instance is a smart pointer and never goes out of scope, hence the destructor is never called.
What I would like to do is when the static instance is first created to return this instance of a smart pointer and then every call there after return a copy of this smart pointer.
A std::weak_ptr is what you're looking for.
By changing the instance to be a weak_ptr, it does not count as an owner to the shared pointer; meaning that once all other references have been released the object is destroyed. That said, it does make your "Get" function a little more complex, in that you must attempt to get a shared_ptr from the weak ptr, then on success return it, or on failure create a new one, re-assign instance to that ptr and return.
You can find more here
As a separate note, the destructor of your static member will be called, just not before main returns. Most people accept this feature of a static since once main returns they don't really care what happens as long as the application doesn't crash (although statics using other statics tends to result in exactly that)
Related
Below is the code which has various return statements and all are working perfectly fine.
Compiler throws the warning for fun_ret_obj1
Test.cpp: In function ‘myClass& fun_ret_obj1()’:
Test.cpp:45: warning: reference to local variable ‘myObj’ returned
But still the output seems to be fine.Is it by Chance?
Are there any catches with any of the return statements below?
Explanation would be really helpful, Thanks
#include <iostream>
using namespace std;
class myClass {
public:
int a ;
myClass()
{
a = 10;
}
};
myClass& fun_ret_add()
{
myClass *ptr = new myClass();
return *ptr;
}
myClass* fun_ret_ptr()
{
myClass *ptr = new myClass();
return ptr ;
}
myClass fun_ret_obj()
{
myClass myObj;
return myObj;
}
myClass& fun_ret_obj1()
{
myClass myObj;
return myObj;
}
int main()
{
myClass obj,obj1;
std::cout <<"In Main \n";
myClass *a = fun_ret_ptr();
std::cout<<a->a<<"\n";
myClass &b = fun_ret_add();
std::cout<<b.a<<"\n";
myClass c = fun_ret_obj();
std::cout<<c.a<<"\n";
myClass d = fun_ret_obj1();
std::cout<<d.a<<"\n";
}
First one is a memory leak:
myClass& fun_ret_add()
{
myClass *ptr = new myClass();
return *ptr;
}
Second one returns a raw pointer (evil - return a std::unique_ptr)
myClass* fun_ret_ptr()
{
myClass *ptr = new myClass();
return ptr ;
}
Third one is perfect - returns a copy, which will almost always be elided. In c++17 it's guaranteed to be elided. This is efficient and safe.
myClass fun_ret_obj()
{
myClass myObj;
return myObj;
}
update
In c++17 you could guarantee the elision of the copy this way:
myClass fun_ret_obj()
{
return myClass{};
}
end of update
Fourth one is undefined behaviour. Returning a reference to a non-existent object. Never do this.
myClass& fun_ret_obj1()
{
myClass myObj;
return myObj;
}
regarding memory leaks
It is true that in the first example, a caller could release the memory if he/she knew that myClass had been allocated with new:
auto& x = fun_ret_add(); // a
...
delete std::addressof(x); // b
This would require:
That the caller knows that fun_ret_add() is implemented in terms of new.
That the implementation of fun_ret_add() never changes
That no exceptions occur between (a) and (b)
The second example is similar. In this case, at least there is a hint that the object needs to be deleted, but the caller must still know that the object has been allocated with new, and he must guard against exceptions.
Contrast with this:
std::unique_ptr<myClass> fun_ret_ptr()
{
return std::make_unique<myClass>();
// or
return { new myClass() };
// or
return std::unique_ptr<myClass>(new myClass());
}
Now the caller receives a smart pointer. If the caller does nothing but use this pointer, the myClass object will be properly deleted when the pointer goes out of scope, and all memory will be reclaimed.
myClass& fun_ret_obj1()
{
myClass myObj;
return myObj;
}
This creates a local variable on the stack, myObj. And returns a reference to that object. Then the object is destroyed because of it's scope. The moment the caller sees the reference it's referencing a stack object that has been destroyed, using it is undefined behaviour. And thus your compiler warns you about that.
OK some explanations:
myClass fun_ret_obj()
{
myClass myObj;
return myObj;
}
This one simply calls a copy-constructor. Nothing really special here.
myClass* fun_ret_ptr()
{
myClass *ptr = new myClass();
return ptr ;
}
This one returns a pointer to a heap allocated object. It will never be deleted until you manually delete it. But it's safe to return.
myClass& fun_ret_add()
{
myClass *ptr = new myClass();
return *ptr;
}
This one will return a reference to the value. While this is OK. You can not access the pointer ptr anymore and thus not delete the object manually. (OK you still could delete the object but you have to know later that this object was initially created on the heap and not on the stack to not cause any strange errors elsewhere. So this is likely to not get deleted later)
myClass& fun_ret_obj1()
{
myClass myObj;
return myObj;
}
This one is critical. The moment the function goes out of scope the destructor will be called. (if you set a to a invalid value in the destructor you will see this).
Because the computer is "smart" and just says "this memory can be overwritten when needed" it gets not "deleted" (the destructor gets called though just not the memory location invalidated). So directly accessing the memory afterwards results in what seems like valid behavior. But this is just by accident. When you would initialize some variables or have some memory allocations on the stack this would get overwritten and you access strange memory. That's why this is undefined behavior and the compiler warns you here.
It's by chance. Your compiler doesn't lie.
Here:
myClass& fun_ret_obj1() {
myClass myObj;
return myObj;
}
You are returning a reference to an object that is going to be destroyed.
You are going to face what is called undefined behavior, it could either works or not.
In your case:
the output seems to be fine
And it's by chance, of course.
myClass fun_ret_obj()
{
myClass myObj;
return myObj;
}
Looks innocent enough, but under the hood will create two temporaries (invoking the ctor on each, which propagates to ctors of all member objects, and so on...). Then when returning will copy the first temporary to the other before deleting it (invokes its dtor and the dtor of all member objects, and so on...), will then invoke the copy ctor (or assignment operator and those of its member objects, and so on...) for the receiving object in the caller, then delete the second temporary (invoking the dtor and the dtor of all member objects, etc...). Even if myClass and of its all member objects have implemented move semantics this may actually be a very heavy duty operation. Better to pass a reference parameter to the receiving object and perhaps use a POD sentinel (success/fail) as the function return type, or use std::unique_ptr as described perfectly by Richard.
I know this is very silly question about singleton pattern but still it is first choice of interviewer.
Could you let me know in below code snippet.
(1) After deleting singleton object why still I am able to call show() method and it works fine.
delete obj;
obj=NULL;
obj->show();
(2) After creating obj1 object why i am not able to print the content of acquire_lock and release_lock function even print statment "one Time" will be printed once and if we increment counter i then instead of 2 it is printing 1 only, why?
Foo *obj1=MySingleton<Foo>::GetInstance();
(3) usage of unique_ptr with singleton object will have any negative implications.
code snippet:
#include <iostream>
#include <fstream>
#include <memory>
#include <string>
using namespace std;
static int i;
class Lock
{
public:
Lock(){};
~Lock(){};
void acquire_lock()
{
cout<<"aquired lock for class";
}
void release_lock()
{
cout<<"released lock for class";
}
};
class Foo
{
public:
void show()
{
cout<<"\ndone\n";
}
};
template <class T>
class MySingleton
{
protected:
MySingleton() {}
private:
//holds one and only object of MySingleton
static T* m_pOnlyOneInstance;
MySingleton(const MySingleton <T> &) {};
MySingleton <T> & operator=(const MySingleton <T> &) {};
~MySingleton() {};
public:
static T * GetInstance();
void foo()
{
cout<<"Mohan";
}
};
template <class T>
T* MySingleton<T>::GetInstance()
{
Lock lock;
if (m_pOnlyOneInstance == NULL)
{
lock.acquire_lock();
cout<<"one Time"<<endl;
i++;
if(m_pOnlyOneInstance == NULL)
{
m_pOnlyOneInstance = new T();
}
lock.release_lock();
}
return m_pOnlyOneInstance;
}
template <class T> T* MySingleton<T> :: m_pOnlyOneInstance=NULL;
int main()
{
//std::unique_ptr <Foo> obj (MySingleton<Foo>::GetInstance());
Foo *obj=MySingleton<Foo>::GetInstance();
//obj->show();
delete obj;
obj=NULL;
obj->show();
cout<<"\ncalling again\n";
Foo *obj1=MySingleton<Foo>::GetInstance();
obj1->show();
cout<<"i="<<i;
return 1;
}
Note: lock related function are dummy implementation only.
Keep in mind that obj->show() is equivalent to Foo::show(obj). Both expressions set this to the value of obj within the show member function. Now, what would setting this to NULL within show do? Nothing, because you never reference this.
Well, think about the whole reason you would use the singleton pattern in the first place -- to initialize something at most one time. That "one time" print statement is in the code where the object gets instantiated, so naturally it doesn't get executed after the first time. Look at the logic of GetInstance. If an instance does not exist, it instantiates the class (messily... but it does work), and afterwards the instance exists. Otherwise, it does nothing.
This question is very unclear, but what I assume you mean is "what are the negative implications of doing std::unique_ptr<Foo> obj = MySingleton<Foo>::GetInstance();?" As you can see from the reference for unique_ptr, its purpose is to take ownership of a dynamically allocated resource. This is definitely not supposed to happen when you're dealing with singleton objects. Because the resource (the singleton instance, in this case) is shared among any number of callers, the singleton class is the only one which should be managing the instance resource -- this is a fundamental invariant of the singleton pattern. If you use unique_ptr, as soon as obj goes out of scope, it will delete the instance automatically, regardless of whether your program references the now-freed instance elsewhere.
This is not a proper way to delete the singleton object, you need to write below method in order to delete the instance and then execute your programme.
static void cleanup()
{
delete m_pOnlyOneInstance;
m_pOnlyOneInstance= NULL;
}
Here is the output :
aquired lock for classone Time
released lock for class
done
calling again
aquired lock for classone Time
released lock for class
done
i=2
(1)
The call would fail if it actually used obj either to perform the call or within the call.
First the call it self is to a non virtual function so the obj pointer is not needed to find the function. The compiler already figured out at compile time which function to call.
Second the function does not access any member variables of the class so while it does receive a this pointer that is NULL it actually never uses it.
BTW, it seems that this code tries to use the MySingleton template to turn other classes into singletons but it doesn't really as it doesn't prevent making copies or instantiating objects through other ways so it is no true singleton. The only thing it does is always return the same pointer.
Other BTW, the second call to MySingleton<Foo>::GetInstance() returns a copy of a pointer that you have previously deleted when you did delete obj. obj was set to NULL after the delete but the original pointer in the MySingleton template is still pointing to the deleted object so the second call to GetInstance will happily return the now invalid pointer.
Your singleton class should have a private constructor and destructor. The destructor should handle any memory cleanup when the scope of the singleton ends, so there's no need to explicitly delete it. It could be unsafe to delete it when other objects are still accessing the singleton after the point of deletion. You could be getting an undefined behavior when you did "delete obj", and "obj=null" since you overloaded assignment operator and destructor are private.
I need to have a singleton class as I need to initialise some variables only once. I have a problem when I can't to clean up the class as it is crashing. Here is a cut down version of my class:
#include "stdafx.h"
#include <iostream>
class MyClass
{
public:
MyClass();
virtual ~MyClass();
static MyClass& Instance();
void DoSomething();
};
MyClass::MyClass()
{
std::cout<<"MyClass constructor"<<std::endl;
//initialise some stuff here
}
MyClass::~MyClass()
{
std::cout<<"MyClass destructor"<<std::endl;
//clean up some stuff here
}
MyClass& MyClass::Instance()
{
static MyClass _instance;
return _instance;
}
void MyClass::DoSomething()
{
std::cout<<"Do something"<<std::endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
MyClass& myClass = MyClass::Instance();
myClass.DoSomething();
delete &myClass;
return 0;
}
When I call the delete &myClass the destructor gets called and then it blows up like so:
I have investigated and I think that I shouldn't be calling delete on an object that has not been created using new. Is this correct??
Is the answer simply don't use any delete and let the destructor be called automatically when it goes out of scope (When main returns)?
I shouldn't be calling delete on an object that has not been created using new.
Absolutely. It's a static object, which will be destroyed automatically at the end of the program. There's no need (and no way) to destroy it yourself.
(Note that, being static, it's not destroyed when it goes out of scope when Instance() returns. Instead it's destroyed at the end of the program, after returning from main() or calling exit()).
When the static object goes out of scope, they will be deleted automatically, so dont bother calling delete on a static object and you should be fine
Your error is due to the delete (as mentioned by others).
I need to have a singleton class as I need to initialise some variables only once.
No, you really (really, really) don't. Singletons solve the problem of centralizing values/settings, while introducing hidden state, tightening module coupling, hiding module dependencies and rendering code untestable.
Consider using dependency injection instead.
#include <iostream>
#include <fstream>
#include <cstdio>
using namespace std;
class Derived
{
public:
Derived()
{
cout<< "Initialize...\n";
}
~Derived()
{
cout<< "Finalize...\n";
}
};
static Derived *obj=new Derived();
int main()
{
cout<<"Main Started::\n";
}
I'm trying to get the output as:
Initialize
MainStarted
Finalize
But getting:
Initialize
MainStarted
I tried to debug but its not getting into destructor. So I'm unable solve this problem.
You need to use
static Derived obj;
instead of
static Derived *obj=new Derived();
Now you create object with new, and never call delete, thus object will never be properly deleted.
Or you can use boost::scoped_ptr if you need heap allocated object for some reason.
static Derived *obj=new Derived();
That's a leak - the object has dynamic storage duration (since you've created it with new), and nothing deletes it, so it will never be destroyed.
If you want it to be destroyed automatically, then give the object static storage duration:
static Derived obj;
Alternatively, instead of defining a class with a destructor, you can use std::atexit to register an arbitrary function to call when the program exits:
#include <iostream>
#include <cstdlib> // for atexit
void goodbye() {std::cout << "Goodbye\n";}
int main() {
std::atexit(goodbye);
std::cout << "Hello\n";
}
Don't make the derived object a pointer. Since C++ is not java, there is little need for new in your case. But if you create the Derived on the heap, you'll have to make sure that it gets destroyed properly, by using RAII, i.e. a smart pointer. In your code you have a memory leak, the destructor of *obj gets never called.
Examples for how to do it right:
static Derived obj; //non-heap version
//C++03 auto_ptr, now deprecated:
static std::auto_ptr<Derived> obj(new Derived());
//C++11 smart pointers:
static std::unique_ptr<Derived> obj(new Derived());
static auto obj = std::make_shared<Derived>();
//Boost smart pointers, C++03 compatible:
static boost::shared_ptr<Derived> obj = boost::make_shared<Derived>();
static boost::scoped_ptr<Derived> obj(new Derived());
Pick one (the first, preferably).
Edit: But before you do any of these, you should give a really good reason for using that global variable.
you are using static Derived *obj=new Derived() but instead of use static Derived obj1 this will print as per your requirements.
I know there are methods to prevent a class from being created on the heap, by preventing the user from using the new and delete operator. I am trying to do just the opposite. I have a class that I want to prevent the user from creating an instance of it on the stack, and that only instances instigated using the new operator will compile. More specifically, I want the following code to receive an error during compilation:
MyClass c1; //compilation error
MyClass* c1 = new MyClass(); //compiles okay
From searching the web, I found this suggestion on how to do it:
class MyClass {
public:
MyClass();
private:
void destroy() const { delete this; }
...
private:
~MyClass();
};
int main(int argc,char** argv)
{
MyClass myclass; // <--- error, private destructor called here !!!
MyClass* myclass_ptr = new MyClass;
myclass_ptr->destroy();
}
What I don't understand is why this should work. Why would the destructor be called while creating an instance of MyClass?
When myclass reaches the end of its scope (the next }) the compiler calls the destructor to free it from the stack. If the destructor is private, however, then the destructor cannot be accessed, so the class cannot be placed on the stack.
I don't like the look of delete this. In general I think objects should not destroy themselves. Perhaps a better way is to have a private constructor for your class then use a static function to create an instance.
// In class declaration...
static MyClass* Create()
{
return new MyClass(); // can access private constructor
}
// ...
MyClass myclass; // illegal, cannot access private constructor
MyClass* pMyClass = MyClass::Create();
delete pMyClass; // after usage
Why would the destructor be called while creating an instance of MyClass?
It isn't. It must be invoked automatically when the instance goes out of scope, though. If it's private, the compiler must not generate that code, hence the error.
If you think making the destructor private is obscure, another way to restrict a class to dynamic allocation is to make all the constructors private and only have MyClass::create() functions returning dynamically allocated objects:
class MyClass {
public:
static MyClass* create() {return new MyClass();}
static MyClass* create(const Foo& f) {return new MyClass(f);}
private:
MyClass();
MyClass(const Foo&);
};
Note that returning naked pointers to objects that must be deleted is frowned upon. You should return smart pointers instead:
class MyClass {
public:
static std::shared_ptr<MyClass> create() {return new MyClass();}
static std::shared_ptr<MyClass> create(const Foo& f) {return new MyClass(f);}
// ...
};
Because when instance goes out of scope, it has to be destructed using destructor. Pointer to instance does not do this.
Whenever a local variable goes out of scope, it is destroyed.
And on destruction, destructor of object is called. Here, scope is of main function. When program exits, myclass object's destructor will be called
It isn't. The compiler is trying to call the destructor when it goes out of scope, and is indicating to the line of code that produces this effect, which is much more useful than pointing at the end of the function.