How do I * not * delete a member in a destructor?

I would like the destructor of my class to delete the entire object, except for one of the members, which is deleted elsewhere. First of all, is it completely unreasonable? Assuming no, how can I do this? I thought that creating a destructor with an empty body would prevent all members from being deleted (because the destructor did nothing), but that doesn't seem to be the case.

+6
c ++ destructor ownership-semantics
source share
12 answers

The short answer . You do not do this.

Longer answer . If the "member" is actually a pointer to some other distribution, you can arrange not to delete another distribution.

But usually, if you select another block in the constructor, you want to delete it in the destructor. Everything else will require careful handling of the "ownership" of the block in question. It will be very similar to memory management in simple c. Perhaps, but fraught with danger.

Good luck.

+15
source share

Depends on what you mean by "remote." If they are not in the smart pointer and are not explicitly deleted, they are not deleted. Members that are part of the class:

class Bar { //... private: Foo foo; }; 

They are not deleted by the destructor (since they were not dynamically allocated), they are simply destroyed. They "live" inside the class, so as soon as it is destroyed, it disappeared.

If you are viewing the share of “ownership” between two locations, then you want to dynamically allocate shared_ptr:

 #include <memory> class Bar { // ... private: std::tr1::shared_ptr<Foo> foo; }; 
+10
source share

If an element is contained by value (not by pointer or by reference), you cannot prevent its deletion, and you should not want it.

If you want to delete it elsewhere, make it contained in a pointer or link.

 class House { Door door; //contained by value, will be destroyed when the House is } class House { Door& door; //contained by reference, will not be destroyed when the House is } 
+4
source share

The code in the destructor is intended only to remove members dynamically allocated. Killing members is not optional, you can control the release of what you explicitly allocated before (with the new operator).

What you want to do can be obtained using shared_ptr, in which both your class and the external code share a pointer to the same external object. Thus, only when all pointers to this object go out of scope will it be deleted. But be careful not to make circular references, shared_ptr does not have the wisdom of a "garbage collector."

Of course, you could use a regular pointer shared by these places, but in most cases this is a bad idea, prone to headaches if you need to free up resources later.

+3
source share

First of all, if a member object is contained in a value, it simply goes out of scope when the container object is destroyed, and you cannot prevent it from being released automatically.

If your container object is indirectly referencing instead (for example, with a pointer), you do not need to do anything, in particular, so as not to delete it. The destructor does not delete anything unless you explicitly write code for this.

Regarding the question of whether this is unreasonable, I think that this is not at all, but you should clearly clarify (as a rule in the documentation, since C ++ does not support the language concept), which is an object that belongs to a member, in question.

+2
source share

I think that in most cases you ask for trouble if you do not destroy the entire object in the same action. It looks like your class should have a cleanup method for this member, which is called inside the destructor. If for some reason the participant must be destroyed earlier, the method may return earlier.

+1
source share

First of all, is it completely unreasonable?

I would not say that this is unreasonable, perhaps doubtful.

This is absolutely true so that one class owns and therefore must take care of cleaning, and at the same time have a link or pointer to this object in another class.

However, it may be doubtful if the second reall class had this pointer or not, I would prefer to always use the get-method to retrieve this pointer whenever I need it, for example. by calling the parent class or some resource manager.

0
source share

If you have dynamically allocated memory for this member, it is possible as soon as you shared a link to this member before destroying the object, and if you make sure that the element is not destroyed in the destructor of the object. However, I believe that this practice is not so reasonable.

0
source share

When you say that class members are deleted in the destructor, you must distinguish between members that are not pointers and those that are. Let's say you have a class like this:

 class Foo { public: Foo() {p = new int;} ~Foo(){} private: int a; int *p; }; 

This class has 2 data elements: an integer a and a pointer to an integer p . When the destructor is called, the object is destroyed, which means that the destructors for all its members are called. This happens even if the body of the destructor is empty. In the case of a primitive type, such as an integer, a call to its destructor means that the memory it occupies will be released. However, when you destroy a pointer, there is a catch: everything that it points to is not destroyed by default. To do this, you must explicitly call delete .

Thus, in our example, a will be destroyed when the destructor is called, and there will be p , but not everything that p points to. If you want to free the memory for which p indicates, the destructor for Foo should look like this:

 ~Foo() {delete p}; 

So, back to your question, all members of your class that are not pointers will be destroyed regardless of when the object's destructor is called. On the other hand, if you have members that are pointers, then what they point to will not be destroyed unless you specifically name delete for them in the destructor.

0
source share

Why didn't anyone mention weak and strong pointers?
A strong pointer is a smart pointer that acts normally.
A weak pointer is a smart pointer that cannot delete itself if all strong pointers fall out of scope.
A strong pointer indicates ownership, a weak pointer indicates sharing.
See boost.shared_ptr and boost.weak_ptr and Loki StrongPtr for an implementation.
Also take a look at RAII . If you knew RAII, you yourself would know the answer to this question.

0
source share

This is not unreasonable, but care should be taken to ensure that the cleanup of any managed resources is processed implicitly.

(The first managed resource that people usually worry about is memory, but all that can leak - memory, file descriptors, IDispatch pointers - must have code that handles the cleanup implicitly).

For managed resources shared by multiple objects (almost certainly if "this object" should have a pointer to what is cleared by "this object"), you usually need either a "reference count pointer" to control the object or a "weak pointer", depending on your life requirements.

For managed resources that are not publicly available (and in particular those that need to be managed properly when exceptions can be thrown), then the auto_ptr option or another option may be more appropriate.

Effective C ++ books by Scott Meyers were a reasonable starting point for learning smart pointers, but in practice you should probably just take a trusted library like Boost and let someone else worry about getting obscure corner cases (like what happens if the constructor throws an exception?) correctly.

0
source share

It is possible, but basically, as @dmckee said this is a property issue. If so, you can go for recalculation. i.e.

 class A { RefObj* obj; A() { obj = new RefObj; } ~A() { obj->ReleaseRef(); } } RefObj { int m_iRefCounter; RefObj() { m_iRefCounter = 1; } AddRef() { m_iRefCounter++; } ReleaseRef() { m_iRefCounter-- if(m_iRefCounter == 0) { delete this; } } } 

}

0
source share

All Articles