1

I simply don't get why the destructor is being called when the object is passed as a parameter to a constructor of another class. This is the part of code where the problem shows up:

Ocean* sea=new Ocean(4,3,7);
sea->print();
RunLengthEncoding* s2= new RunLengthEncoding(*sea);
sea->print();

the code of the constructor:

RunLengthEncoding::RunLengthEncoding(Ocean sea)
{
oceanEncoding = new MyLinkedListD();
height = sea.height();
width=sea.width();
starveT=sea.starveTime();
int length=1;
int cellType=sea.cellContents(0,0);
int hunger=sea.sharkFeeding(0,0);
for(int row=0;row<height;row++){
    for(int col=0;col<width;col++){
        if(row==0&&col==0){
            cellType=sea.cellContents(col,row);
            hunger=sea.sharkFeeding(col,row);
        }
        else{
            if(sea.cellContents(col,row)==cellType && ((cellType==Ocean::SHARK && hunger==sea.sharkFeeding(col,row))|| cellType!=Ocean::SHARK)){
                    length++;
            }
            else{
                oceanEncoding->add(cellType,length,hunger);
                cellType=sea.cellContents(col,row);
                length=1;
                hunger=sea.sharkFeeding(col,row);
            }
        }
    }
}
oceanEncoding->add(cellType,length,hunger);
internalPointer=oceanEncoding->getHead();
check();

}

  • 9
    You need to show the signature of the function (ctor) you are calling, my crystal ball says that it is taking the parameter by value. – PlasmaHH Jun 14 '13 at 20:42
  • 5
    How do you know the destructor is being called? – David G Jun 14 '13 at 20:42
  • when i print it after constructing the new object it prints rubbish – Mai Ibrahim Jun 14 '13 at 20:46
  • @MaiIbrahim: That by no means is a way to detect if the dtor is run. – PlasmaHH Jun 14 '13 at 20:47
  • In general whenever i try to use this object again. it doesn't work properly – Mai Ibrahim Jun 14 '13 at 20:52
  • 2
    @MaiIbrahim If your second `print()` call is printing junk, then I'm guessing this `Ocean` class is managing some resource, and you either haven't implemented a copy constructor, or if you have, it's not implemented correctly. That's why the destructor is freeing the resource, and leaving you with an object that now points to invalid resources. Read about the [rule of three](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three). – Praetorian Jun 14 '13 at 21:06

3 Answers3

8

The constructor is taking its argument by value. A copy is made, used, and then destroyed when the constructor returns.

Take the argument by reference (const reference is best).

Michael Mrozek
  • 169,610
  • 28
  • 168
  • 175
Ed S.
  • 122,712
  • 22
  • 185
  • 265
  • i can not change the argument of the constructor its written by my instructor – Mai Ibrahim Jun 14 '13 at 20:48
  • Normally one writes copy constructors with a signature like this: `Foo(const Foo& other)`. The answere guesses that the constructor might look like this `Foo(Foo other)`. – Sebastian Hoffmann Jun 14 '13 at 20:51
  • 3
    @MaiIbrahim: Then a destructor is going to be called, simple as that. Your constructor takes a *copy* of an object, not a reference to one and not a pointer to one. That means that a copy will be created. The copy will go out of scope when the constructor returns, thus, the destructor is called. Your teacher is instructing you to write code that you would never write in a real application. – Ed S. Jun 14 '13 at 20:51
1
RunLengthEncoding(*sea);

This takes a value. Not a pointer to a value, nor a reference to a value. The compiler inserts code to create a value and passes it to the function. Inside the function, if you modify the value it doesn't change the one you imagine you are passing in. After the function is called the value is destroyed.

*sea is not passed into the function. It can not be modified inside the function.

Peter Wood
  • 23,859
  • 5
  • 60
  • 99
  • i know, i don't want it to be modified but what i was imagining to happen is that it takes a copy of it sends it to the function ,executes the function, destroys the copy and the other one stays as it is. – Mai Ibrahim Jun 14 '13 at 21:00
  • I think I know what's happening. You have a copy constructor which is passing the internals of the `sea` object to the temporary, so they are sharing them. When the temporary is destroyed it destroys some parts which `sea` still holds as precious. In your copy constructor you need to create a copy of the internals of `Ocean` (anything which is a pointer). – Peter Wood Jun 14 '13 at 21:30
  • I've got where the problem is but i still don't get how to fix it, i've tried inside the constructor to make a pointer that points to sea but it doesn't change anything. – Mai Ibrahim Jun 16 '13 at 00:22
0

Since the constructor is taking its argument by value once the function is over the object goes out of scope and is thus destroyed. Since you cannot change the argument of the constructor the object will always be destroyed so the only way around this is to create a new copy of the object allocated on the heap (so it won't be destroyed) however this isn't really good coding practice

aaronman
  • 18,343
  • 7
  • 63
  • 78