deconstructor called after constructor

Started by
19 comments, last by Brother Bob 16 years ago
That probably means that you didn't write your assignment operator correctly.
Advertisement
Quote:Original post by SiCrane
That probably means that you didn't write your assignment operator correctly.


actually i didnt write an assignment operator at all. do i have to?
If in doubt, print out the function being called, and the address of the this pointer (And the other object pointer if it exists) for the following functions:
Default constructor
Copy Constructor
Destructor
Assignment operator

Also, make sure your copy constructor and assignment operator take one argument, a const reference to another object, and that your assignment operator returns *this at the end of it.
If you write a copy constructor, assignment operator or destructor it probably means that you need to write all of them. This is called the rule of three.

Alternately you can switch from manually managing memory to something like a std::vector.
Quote:Original post by Evil Steve
If in doubt, print out the function being called, and the address of the this pointer (And the other object pointer if it exists) for the following functions:
Default constructor
Copy Constructor
Destructor
Assignment operator

Also, make sure your copy constructor and assignment operator take one argument, a const reference to another object, and that your assignment operator returns *this at the end of it.


EDIT:
Quote:Original post by ehmdjii
actually i didnt write an assignment operator at all. do i have to?
Depends. The default one just calls operator= for each class member (Which is just a copy for primtive types). If you need different behaviour (If you have any pointers as members, this is likely), you'll need to provide your own assignment operator.
ok thanks.

yes i am using pointers as members of this class.

would changing the situation to a pointer solve my problem?

myClass* foo = new myClass();foo->operateOnArray();foo = new myClass();foo->operateOnArray();


will the destructor be correctly called on the OLD object?

basically i just want to create a new instance and save it in the variable foo, while the old instance gets its destructor called correctly.

thanks!
Quote:Original post by ehmdjii
ok thanks.

yes i am using pointers as members of this class.

would changing the situation to a pointer solve my problem?

*** Source Snippet Removed ***

will the destructor be correctly called on the OLD object?

basically i just want to create a new instance and save it in the variable foo, while the old instance gets its destructor called correctly.

thanks!
No destructor will be called in the above code because the object is on the heap. The destructor will be called by delete, or if you call it manually (Which isn't something you want to be doing). That code will cause a memory leak unless you add a delete call:
myClass* foo = new myClass(); // Create a new myClass obj on the heap. Assign address to foofoo->operateOnArray();delete foo; // Delete foo: call destructor and free memory. foo is now an invalid pointerfoo = new myClass(); // Create a new myClass obj on the heap. Assign address to foofoo->operateOnArray();


What exactly are you trying to do here? Generally if assignment is expensive (Which can be the case when you have pointers to dynamic memory as members, since you may need to reallocate that memory) you'd use pointers to objects, and objects otherwise.

I'd also recommend looking into smart pointers (Boost has a few types), which may solve your problems.
No, you didn't delete the old object, so the destructor isn't called.

That is known as a leak.

When you call "new", you are now in charge of making sure that object is deleted at the end of it's lifetime.

...

Some advice on constructors and destructors.

First, make sure everything your copy constructor does you deal with in your destructor, AND everything your default constructor does you deal with in your destructor. Realize that the object you copied from will still exist after the copy constructor.

In short: your copy constructor AND your default constructor AND every other constructor should allocate the same resources, usually.

Then your destructor cleans them up.

Next, operator= -- ie, the assignment operator.

An easy way to write operator= that doesn't screw up is to first write a "swap" function.

class foo {  public:    void swap(foo& other) { ... };    // ...};

What swap does is it, well, swaps. It takes all of the resources owned by this, and all of the resources owned by other, and swaps who owns each. The state of the two objects changes hands.

Use of the #include <algorithm> std::swap is useful when implementing your own swap. :)

Now, you can write a really simple operator=:
class foo {  public:    foo& operator=(const foo& other) {      foo tmp = other; // copy constructor      this->swap(tmp); // swap our state      return *this; // the tmp object is destroyed, taking our resources with us!    }};


Slick, eh? You move the tricky resource management code out of the operator=, and into the constructor/destructor only. The only disadvantage is that you don't get to recycle resources -- but the increased simplicity of code is often worth it.
thank you everyone! i understand it now!
Quote:Original post by NotAYakk
Now, you can write a really simple operator=:
class foo {  public:    foo& operator=(const foo& other) {      foo tmp = other; // copy constructor      this->swap(tmp); // swap our state      return *this; // the tmp object is destroyed, taking our resources with us!    }};
I presume this:
foo tmp = other; // copy constructor
Should be this:
foo tmp(other); // copy constructor
?

This topic is closed to new replies.

Advertisement