C++ destructor question

CU

Platinum Member
Aug 14, 2000
2,419
53
91
Since your destructor should free up all your memory can, can you just do this? That way calling the destructor frees all your memory for you, but doesn't delete the object and then just use your constructor method to copy the new data over.

 

CU

Platinum Member
Aug 14, 2000
2,419
53
91
The returns didn't work in the code window. Why didn't they? Anyway it looks like this.

CFoo& CFoo::eek:perator=(const CFoo& f)
{
if(this != &f)
{
this->~CFoo();
*this = CFoo(f);
}

return *this;
}
 

Markbnj

Elite Member <br>Moderator Emeritus
Moderator
Sep 16, 2005
15,682
14
81
www.markbetz.net
Yeah, the code attachment doesn't work. It eats newlines and other forms of whitespace.

I can't really tell if you're asking a question, or passing along a tip :). Explicit destructor calls are allowed, and used in the STL among other places, but probably more often in the case that placement new is used to override memory allocation at construction.

This statement looks like it would cause a recursive call to the assignment operator:

*this = CFoo(f);

But I don't understand the semantics you're trying to achieve with your assignment operator in general. Assignment means a copying of value (state), just as with a copy constructor (which I used to implement by calling the assignment operator). You're destroying the existing object and then invoking the copy ctor to create a temp, followed by the (possibly recursive) call to the assignment operator. Why not just do a member-wise copy and deep-copy any pointers?
 

degibson

Golden Member
Mar 21, 2008
1,389
0
0
On a related note, if CFoo contains no non-primitive data types, a quick way to copy a bunch of member variables is to do this:

memcpy( this, &f, sizeof(CFoo) );

Edit: 'Quick' as in 'not much to type'. It shouldn't be any faster than a list of individual member copies (in fact, it could be slower).
 

CU

Platinum Member
Aug 14, 2000
2,419
53
91
I am not destroying CFoo just freeing its dynamic memory by explicitly calling the destructor. At least that is my understanding of calling it explicitly. Although *this = CFoo(f); is recursive and will cause a crash. My goal was to keep from duplicating so much code between the copy constructor and assignment operator. CFoo in my case has several maps full of pointers. Actually it has several maps of maps of pointers also. Those are std::maps so everything is shallow, so I need to free/create memory for all those pointers and copy the data over.
 

degibson

Golden Member
Mar 21, 2008
1,389
0
0
Originally posted by: CU
...My goal was to keep from duplicating so much code between the copy constructor and assignment operator...

How about this:

class CFoo {
public:
CFoo() {}
CFoo( const CFoo &other ) { SnarfFrom(other); }

operator=(const CFoo &other) { SnarfFrom(other); }

private:
void SnarfFrom( const CFoo &other);

int m_nInt1;
int m_nInt2;
...
};

extern inline
void CFoo::SnarfFrom( const CFoo &other ) {
m_nInt1 = other.m_nInt1;
m_nInt2 = other.m_nInt2;
...
}

Edit: Bloody h*** I know I've complained about this before, but we really need a better way to attach code. Can we embed HTML...? GVIM spits out nice syntax highlights.
 

degibson

Golden Member
Mar 21, 2008
1,389
0
0
Another implementation of SnarfFrom() for primitive data types:

extern inline
void CFoo::SnarfFrom( const CFoo &other ) {
memcpy( this, &other, sizeof(CFoo) );
}
 

CU

Platinum Member
Aug 14, 2000
2,419
53
91
Yeah that would work except for all the pointers I have in the maps. I could add a flag parameter to SnarfFrom() to tell it if it was called from the copy constructor or the assignment operator. Then based on that I would know how to handle my pointers. I will have to look at my code tomorrow and see how that would work out.
 

degibson

Golden Member
Mar 21, 2008
1,389
0
0
Originally posted by: CU
Yeah that would work except for all the pointers I have in the maps. I could add a flag parameter to SnarfFrom() to tell it if it was called from the copy constructor or the assignment operator. Then based on that I would know how to handle my pointers. I will have to look at my code tomorrow and see how that would work out.

Rather than modify SnarfFrom(), add another private function, FreeAllMem(), that is called by both the destructor and operator=(), the latter just before calling SnarfFrom().

Naturally, a Snarf method can be made to work with arbitrary data members (i.e. pointer variables can be cloned if needed).
 

CU

Platinum Member
Aug 14, 2000
2,419
53
91
Wouldn't FreeAllMem() do the same as calling the destructor explicitly? Either way I think the parameter approach would work better for me so I don't have to loop through all my maps deleting memory in FreeAllMem() the again creating memory in SnarfFrom(). I could just check the flag to decide if I should delete memory or not.
 

CU

Platinum Member
Aug 14, 2000
2,419
53
91
Well calling the destructor explicitly does destroy the object and doesn't just free the memory of it dynamic member variables. I tried it, it completely deallocated everything not just what I was calling delete on in the destructor. Now I have a FreeMemory() function to call in both places. I could not use the parameter approach because I forgot my maps may not be the same size in both CFoo's. So I have to loop through to free up all the memory, then copy the maps, and then loop though the new maps again and create the new objects in the maps.

This has been a very good learning exercise for me. I has been awhile since I have overloaded all these operators on such a large object. And to top it off this class is a hybrid singleton class. You can use it as a singleton or as a normal class at the same time. Some of the functions check if it was called from the singleton instance or a normal instance and react differently depending on its type. I have never done or seen that done anywhere before. Maybe for good reason, and I just haven't hit the problems it causes.