Having this:
class Foo
{
public:
void destroy() { delete this; }
public:
// Stuff here...
};
int main(int argc, char *argv[])
{
Foo* foo = new Foo;
// Option 1
delete foo;
// Option 2:
foo->destroy();
return 0;
}
Is Option 1 and Option 2 the same operation? Is it a 'correct' way for destroying objects? Why/Why not?
Thank you so much,
Yes, the two are equivalent in this case.
But you should definitely prefer Option 1. delete this is very easy to get wrong, violates various design principles, and in this instance is completely pointless.
Such destruction schemes (a member function deleting the this pointer) are the common solution when implementing classes that allow instances only on the heap
class Foo
{
~Foo(); // private destructor - won't allow objects on the stack
public:
void destroy() { delete this; }
public:
// Stuff here...
};
In the above example, the destructor can't be called, so you can't say
delete FooInstance;
and your only option to avoid memory leaks is to have a destroy function:
FooInstance->destroy();
Apart from that I haven't found any real world cases where such a destruction function is/has to be used.
As others said, it's not common and discouraged. A usually reliable source says that you can technically do it if you strictly follow a few rules; in particular, do not access freed memory or class members after the delete: http://www.parashift.com/c++-faq/delete-this.html.
Option 1 is the recommended way to delete a class object.
class Foo
{
public:
~Foo()
{
//define destructor if you have any pointer in your class
}
public:
// Stuff here...
};
int main()
{
Foo* foo = new Foo;
// By deleting foo it will call its destructor
delete foo;
}
For Option 2
The C++ FAQ Lite has a entry specifically for this
http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.15
As long as you're careful, it's OK for an object to commit suicide (delete this).
Related
Consider the following class:
struct S { ~S() = delete; };
Shortly and for the purpose of the question: I cannot create instances of S like S s{}; for I could not destroy them.
As mentioned in the comments, I can still create an instance by doing S *s = new S;, but I cannot delete it as well.
Therefore, the only use I can see for a deleted destructor is something like this:
struct S {
~S() = delete;
static void f() { }
};
int main() {
S::f();
}
That is, define a class that exposes only a bunch of static functions and forbid any attempt to create an instance of that class.
What are the other uses (if any) of a deleted destructor?
If you have an object which should never, ever be deleted or stored on the stack (automatic storage), or stored as part of another object, =delete will prevent all of these.
struct Handle {
~Handle()=delete;
};
struct Data {
std::array<char,1024> buffer;
};
struct Bundle: Handle {
Data data;
};
using bundle_storage = std::aligned_storage_t<sizeof(Bundle), alignof(Bundle)>;
std::size_t bundle_count = 0;
std::array< bundle_storage, 1000 > global_bundles;
Handle* get_bundle() {
return new ((void*)global_bundles[bundle_count++]) Bundle();
}
void return_bundle( Handle* h ) {
Assert( h == (void*)global_bundles[bundle_count-1] );
--bundle_count;
}
char get_char( Handle const* h, std::size_t i ) {
return static_cast<Bundle*>(h).data[i];
}
void set_char( Handle const* h, std::size_t i, char c ) {
static_cast<Bundle*>(h).data[i] = c;
}
Here we have opaque Handles which may not be declared on the stack nor dynamically allocated. We have a system to get them from a known array.
I believe nothing above is undefined behavior; failing to destroy a Bundle is acceptable, as is creating a new one in its place.
And the interface doesn't have to expose how Bundle works. Just an opaque Handle.
Now this technique can be useful if other parts of the code need to know that all Handles are in that specific buffer, or their lifetime is tracked in specific ways. Possibly this could also be handled with private constructors and friend factory functions.
one scenario could be the prevention of wrong deallocation:
#include <stdlib.h>
struct S {
~S() = delete;
};
int main() {
S* obj= (S*) malloc(sizeof(S));
// correct
free(obj);
// error
delete obj;
return 0;
}
this is very rudimentary, but applies to any special allocation/deallocation-process (e.g. a factory)
a more 'c++'-style example
struct data {
//...
};
struct data_protected {
~data_protected() = delete;
data d;
};
struct data_factory {
~data_factory() {
for (data* d : data_container) {
// this is safe, because no one can call 'delete' on d
delete d;
}
}
data_protected* createData() {
data* d = new data();
data_container.push_back(d);
return (data_protected*)d;
}
std::vector<data*> data_container;
};
Why mark a destructor as delete?
To prevent the destructor from being invoked, of course ;)
What are the use cases?
I can see at least 3 different uses:
The class should never be instantiated; in this case I would also expect a deleted default constructor.
An instance of this class should be leaked; for example, a logging singleton instance
An instance of this class can only be created and disposed off by a specific mechanism; this could notably occur when using FFI
To illustrate the latter point, imagine a C interface:
struct Handle { /**/ };
Handle* xyz_create();
void xyz_dispose(Handle*);
In C++, you would want to wrap it in a unique_ptr to automate the release, but what if you accidentally write: unique_ptr<Handle>? It's a run-time disaster!
So instead, you can tweak the class definition:
struct Handle { /**/ ~Handle() = delete; };
and then the compiler will choke on unique_ptr<Handle> forcing you to correctly use unique_ptr<Handle, xyz_dispose> instead.
There are two plausible use cases. First (as some comments note) it could be acceptable to dynamically allocate objects, fail to delete them and allow the operating system to clean up at the end of the program.
Alternatively (and even more bizarre) you could allocate a buffer and create an object in it and then delete the buffer to recover the place but never prompt an attempt to call the destructor.
#include <iostream>
struct S {
const char* mx;
const char* getx(){return mx;}
S(const char* px) : mx(px) {}
~S() = delete;
};
int main() {
char *buffer=new char[sizeof(S)];
S *s=new(buffer) S("not deleting this...");//Constructs an object of type S in the buffer.
//Code that uses s...
std::cout<<s->getx()<<std::endl;
delete[] buffer;//release memory without requiring destructor call...
return 0;
}
None of these seems like a good idea except in specialist circumstances. If the automatically created destructor would do nothing (because the destructor of all members is trivial) then the compiler will create a no-effect destructor.
If the automatically created destructor would do something non-trivial you very likely compromise the validity of your program by failing to execute its semantics.
Letting a program leave main() and allowing the environment to 'clean-up' is a valid technique but best avoided unless constraints make it strictly necessary. At best it's a great way to mask genuine memory leaks!
I suspect the feature is present for completeness with the ability to delete other automatically generated members.
I would love to see a real practical use of this capability.
There is the notion of a static class (with no constructors) and so logically requiring no destructor. But such classes are more appropriately implemented as a namespace have no (good) place in modern C++ unless templated.
Creating an instance of an object with new and never deleting it is the safest way to implement a C++ Singleton, because it avoids any and all order-of-destruction issues. A typical example of this problem would be a "Logging" Singleton which is being accessed in the destructor of another Singleton class. Alexandrescu once devoted an entire section in his classical "Modern C++ Design" book on ways to cope with order-of-destruction issues in Singleton implementations.
A deleted destructor is nice to have so that even the Singleton class itself cannot accidentally delete the instance. It also prevents crazy usage like delete &SingletonClass::Instance() (if Instance() returns a reference, as it should; there is no reason for it to return a pointer).
At the end of the day, nothing of this is really noteworthy, though. And of course, you shouldn't use Singletons in the first place anyway.
Say I have this class:
class Foo
{
public:
Foo()
{
bar = new Bar;
}
~Foo()
{
if(bar)
delete bar;
}
private:
Bar* bar;
};
Why would I want to use std::unique_ptr instead of raw pointers when unique_ptr is bloated? Are there any advantage? Is there any situation where my destructor won't be called?
The code you have above actually has a bug because you haven't defined a copy constructor or assignment operator. Imagine this code:
Foo one;
Foo two = one;
Because two is a copy of one, it's initialized using the default copy constructor - which makes both bar pointers point to the same object. This means that when the destructor for two fires, it will deallocate the same object shared by one, so one's destructor will trigger undefined behavior. Oops.
Now, if you didn't want to make your object copyable, you could say that explicitly like this:
class Foo
{
public:
Foo()
{
bar = new Bar;
}
Foo(const Foo&) = delete;
Foo& operator= (const Foo&) = delete;
~Foo()
{
if(bar)
delete bar;
}
private:
Bar* bar;
};
So that fixes that problem - but look at the amount of code involved! You had to explicitly delete two functions and write a destructor by hand.
Except there's another problem. Suppose I do this:
Foo one;
Foo two = std::move(one);
This initializes two by moving the contents of one into two. Or does it? Unfortunately, the answer is no, because the default move constructor will default to moving the pointer, which just does a straight pointer copy. So now you get the same thing as before. Oops.
Not to worry! We can fix this by defining a custom move constructor and move assignment operator:
class Foo
{
public:
Foo()
{
bar = new Bar;
}
Foo(const Foo&) = delete;
Foo& operator= (const Foo&) = delete;
Foo(Foo&& rhs)
{
bar = rhs.bar;
rhs.bar = nullptr;
}
Foo& operator= (Foo&& rhs)
{
if (bar != rhs.bar)
{
delete bar;
bar = rhs.bar;
rhs.bar = nullptr;
}
}
~Foo()
{
if(bar)
delete bar;
}
private:
Bar* bar;
};
Phew! That's a ton of code, but at least it's correct. (Or is it?)
On the other hand, imagine you wrote this:
class Foo
{
public:
Foo() : bar(new Bar) {
}
private:
std::unique_ptr<Bar> bar;
};
Wow, that's a lot shorter! And it automatically ensures that the class can't be copied, and it makes the default move constructor and move assignment operators work correctly.
So one huge advantage of std::unique_ptr is that it automatically handles resource management, yes, but another one is that it plays nicely with copy and move semantics and doesn't work in unexpected ways. That's one of the main reasons to use it. You can say what you mean - "I'm the only one who should know about this thing, and you can't share it" - and the compiler will enforce it for you. Enlisting the compiler to help you avoid mistakes is almost always a good idea.
As for bloat - I'd need to see evidence of that. std::unique_ptr is a thin wrapper on a pointer type and a good optimizing compiler should have no trouble generating good code for it. True, there's the constructor, destructor, etc. associated with std::unique_ptr, but a reasonable compiler will inline those calls, which essentially just do the same thing as what you had initially described.
You are basically relying on a class to manage a pointer's lifetime, but neglect to consider that pointers get passed between functions, returned from functions, and generally exist everywhere. What if the pointer in your example needs to outlive the class? What if it needs to be deleted before the class is destroyed?
Consider this function:
Bar * doStuff(int param) {
return new Bar(param);
}
You now have a dynamically allocated object that may leak if you forget to delete it. Perhaps you didn't read the documentation, or perhaps the documentation is lacking. Regardless, this function puts an unnecessary burden on you to destroy the the returned instance of Bar.
Now consider:
std::unique_ptr<Bar> doStuffBetter(int param) {
return new Bar(param);
}
The returned unique_ptr manages the lifetime of the pointer it wraps. The fact that the function returns a unique_ptr eliminates any confusion about ownership and lifetime. Once the returned unique_ptr goes out of scope and its destructor called, the instance of Bar is automatically deleted.
unique_ptr is just one of several methodologies that the standard library provides to make using pointers a less messy process and express ownership. It is both lightweight and works largely like a normal pointer, save for copying.
It is easier to be exception-safe by using std::unique_ptr (RAII) instead of raw pointers.
Consider a class has two member variables acquiring memory in its constructor.
class Foo
{
public:
Foo()
{
bar = new Bar;
car = new Car; // <- What happens when this throws exception?
}
~Foo()
{
if(bar)
delete bar;
if(car)
delete car;
}
private:
Bar* bar;
Car* car;
};
If the constructor of Foo throws exception, Foo is not successfully constructed, therefore its destructor is not called.
When new Car throws exception, bar is not deleted, so there will be a memory leak.
Now consider the code using std::unique_ptr.
class Foo
{
public:
Foo() : bar(std::make_unique<Bar>()), car(std::make_unique<Car>()) {}
private:
std::unique_ptr<Bar> bar;
std::unique_ptr<Car> car;
};
If the constructor of Foo throws exception, Foo is not successfully constructed, therefore its destructor is not called.
However, destructors of successfully created member instances are called.
Even std::make_unique<Car>() throws exception, destructor of bar is called, so there will be no memory leak.
I've stared using smart pointer and trying to wrap my head around best uses for it. I've read plenty of articles but I'm confused on which to use in the following example. I've included a shared_ptr and unique_ptrexamples to show what I'm trying to accomplish:
class A
public:
A();
private:
unique_ptr<B> ptrB;
unique_ptr<SomeObject> ptrUnique;
shared_ptr<SomeObject> ptrShared;
A::A()
{
ptrB(new B());
ptrUnique(new SomeObject());
ptrB->PassUnique(ptrUnique);
ptrShared(new SomeObject());
ptrB->PassShared(ptrShared);
}
class B:
public:
void PassUnique(unique_ptr<SomeObject> &ptr_unique);
void PassShared(weak_ptr<SomeObject> &ptr_weak);
void DoSomething();
private:
unique_ptr<SomeObject> ptrUnique;
weak_ptr<SomeObject> ptrWeak;
B::PassUnique(unique_ptr<SomeObject> &ptr_unique)
{
ptrUnique = ptr_unique;
}
B::PassShared(weak_ptr<SomeObject> &ptr_weak)
{
ptrWeak = ptr_weak;
}
B::DoSomething()
{
ptrUnique->SomeMethod();
shared_ptr<SomeObject> ptr1 = ptrWeak.lock();
ptr1->SomeMethod();
}
SomeObject class can be any class. A good example is a database handle that I pass from the parent class A were it was originally initiated to multiple class like B. And from B to C if it exists. My question is if I'm passing a unique_ptr as a reference will setting for example ptrUnqiue = ptr_unique in B:PassUnique create a copy which then is not correct? Or should this be done via shared_ptr? This understanding is what is confusing with smart pointers for me and would appreciate clarification.
Well, this is a question of lifetime. Do you need SomeObject to outlive A? Do B send or is being use outside of this context? You have to decide when your objects dies. If you think SomeObject exists only in this context, I would recommend A to be the owner, as it allocate the resource, and be to old a raw pointer to SomeObject. I would look like this:
class A
public:
A();
private:
unique_ptr<B> ptrB;
unique_ptr<SomeObject> ptrUnique;
};
A::A()
{
ptrB(new B());
ptrUnique(new SomeObject());
ptrB->PassUnique(*ptrUnique);
}
class B:
pubic:
void PassUnique(SomeObject& obj);
void DoSomething();
private:
SomeObject* ptrUnique;
};
B::PassUnique(SomeObject& obj)
{
ptrUnique = &obj;
}
B::DoSomething()
{
ptrUnique->SomeMethod();
}
There is no such thing as
ptrUnique = ptr_unique;
If you need SomeObject to be used and owned outside of this structure, then go with std::shared_ptr like you did. There were no errors with your std::shared_ptr code.
Answer is basically what would be a lifetime of the pointer in the A, B and/or C. Think of it as ranges, [A...a), [B...b) and [C...c). If [B...b) is always within [A...a) and [C...c) is always within [B...b), they have like a Russian dolls hierarchy, then passing down ref-to-ptr is ok. If ranges overlap and changes wildly so you don't really control where last ptr will be destructed and object will be deleted, you'd have to go with shared_ptr.
My code is like following, basically I am using some external library and embed some class objects from this library to myClass, then do things with OBJ,
#include "extern_lib.h" //some library
class myClass
{
public:
extern_class *obj1;
extern_class *obj2;
double arr[3];
};
int main()
{
myClass *OBJ= new myClass();
OBJ->obj1 = new extern_class(arg1...);
OBJ->obj2 = new extern_class(arg2...);
//do something like
OBJ->obj1->extern_fun1(arg1...);
OBJ->obj2->extern_fun2(arg2...);
//delete
delete OBJ;
return 0;
}
I would like to know,
1- in order to free all the objects, is it enough to delete OBJ?
2- is there better ways to write this code?
No, it is not enough. You have to call delete for every new you place in your code explicitely.
Use smart pointers like std::unique_ptr or better, use RAII. To clarify that: smart pointers and RAII are not even only better ways of doing so, they are the ways of doing it correctly in modern C++.
Here's an adequate example with RAII:
#include "extern_lib.h"
class myClass
{
public: // note that public members are possibly bad design (depending on your situation)
extern_class obj1;
extern_class obj2;
double arr[3];
};
int main()
{
myClass foo;
foo.obj1.extern_fun(arg1...);
foo.obj2.extern_fun(arg2...);
return 0;
}
Please note that it's not possible to use RAII in every situation. If you run into such, use smart pointers as stated:
#include "extern_lib.h"
class myClass
{
public: // note that public members are possibly bad design (depending on your situation)
std::unique_ptr<extern_class> obj1;
std::unique_ptr<extern_class> obj2;
double arr[3];
};
int main()
{
myClass foo;
foo.obj1 = std::unique_ptr<extern_class>(new extern_class(arg1...));
foo.obj2 = std::unique_ptr<extern_class>(new extern_class(arg2...));
foo.obj1->extern_fun(arg1...);
foo.obj2->extern_fun(arg2...);
return 0;
}
In order to free all the objects, is it enough to delete OBJ?
No, this will produce a resource leak as the (default) destructor of myClass doesn't care about deleting the pointer members.
Is there better ways to write this code?
Yes, use smart pointers. For example:
class myClass
{
public:
std::unique_ptr<extern_class> obj1;
std::unique_ptr<extern_class> obj2;
double arr[3];
};
In general, try to make resources owned by classes. That is, allocate them in the constructor and deallocate them in the destructor. The standard library's smart pointers will already do that job for you. Avoid managing more than one resource inside a single class.
By the way: If your example is not contrived and you are really not using polymorphism at all, then just get rid of all those news and simply use variables with automatic storage duration. C++ is not Java.
Update: Here is (one way of) how to get rid of new if polymorphism is not needed:
class myClass
{
public:
extern_class obj1;
extern_class obj2;
double arr[3];
myClass(type arg1a, ..., type arg2a, ...) : obj1(arg1a, ...), obj2(arg2a, ...)
// ^^^^ member initializer list ^^^^
{
}
};
The key is to create the member objects as part of the process of creating myClass by using a so-called member initializer list. If you are programming C++11, prefer writing obj1 {arg1a, ...}, obj2 {arg2a, ...} for consistency. (The old syntax still works equally well, however.)
Likewise in your main function:
int
main()
{
myClass mc(arg1a, ..., arg2a, ...); // (1)
mc.obj1.extern_func(...);
mc.obj2.extern_func(...);
return 0; // (2)
}
At line (1), we create an instance of myClass on the stack using our new constructor that will create the members obj1 and obj2 correctly. The compiler-generated default constructor of myClass will correctly destruct mc.obj1 and mc.obj2 as mc goes out of scope on line (2). Again, in C++11 line (1) can be written more cleanly as myClass mc {arg1a, ..., arg2a, ...};.
I can't remember what it is called, but I know i can do it in Java.
Suppose I have the following:
class Foo
{
public:
Foo() {};
void bar() {};
};
I want to do this:
int main() {
(new Foo).bar();
}
But it doesn't seem to work. Is there a similar way to do this without having to do:
int main() {
Foo foobar;
foobar.bar();
}
new dynamically-allocates memory and returns a pointer. Class members are obtained using the indirection operator ->. I don't think this is what you're looking for as you run the risk of causing a memory leak. Simply calling the constructor of Foo allows us to do what we want:
Foo().bar();
By calling the constructor of Foo, we create a temporary object off of which we can obtain its data members. This is preferred over pointers as we don't have to deal with memory leaks and deletion of the pointer.
You can say (new Foo)->bar();. That works but is absolutely idiotic. The correct thing is this:
int main()
{
Foo x;
x.bar();
}
Or, if you don't want the local variable: Foo().bar();. But now that's questionable, since if you don't need Foo to be stateful, then you probably don't need a class at all. Just make bar a free function (something that doesn't exist in Java):
void bar();
int main()
{
bar();
}
Yes, Foo().bar();. No need to use new like in Java.