Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this C++ reassignment valid?

Tags:

c++

oop

Sorry for the basic question, but I'm having trouble finding the right thing to google.

#include <iostream>
#include <string>
using namespace std;

class C {
public: 
C(int n) {
    x = new int(n);
}

~C( ) {
    delete x;
}

int getX() {return *x;}

private: 
    int* x; 
}; 

void main( )  {
    C obj1 = C(3);
    obj1 = C(4);
    cout << obj1.getX() << endl;
}

It looks like it does the assignment correctly, then calls the destructor on obj1 leaving x with a garbage value rather than a value of 4. If this is valid, why does it do this?


2 Answers

If there is a class C that has a constructor that takes an int, is this code valid?

C obj1(3);
obj1=C(4);

Assuming C has an operator=(C) (which it will by default), the code is valid. What will happen is that in the first line obj1 is constructed with 3 as a the parameter to the constructor. Then on the second line, a temporary C object is constructed with 4 as a parameter and then operator= is invoked on obj1 with that temporary object as a parameter. After that the temporary object will be destructed.

If obj1 is in an invalid state after the assignment (but not before), there likely is a problem with C's operator=.

Update: If x really needs to be a pointer you have three options:

  1. Let the user instead of the destructor decide when the value of x should be deleted by defining a destruction method that the user needs to call explicitly. This will cause memory leaks if the user forgets to do so.
  2. Define operator= so that it will create a copy of the integer instead of a copy of the value. If in your real code you use a pointer to something that's much bigger than an int, this might be too expensive.
  3. Use reference counting to keep track how many instances of C hold a pointer to the same object and delete the object when its count reaches 0.
like image 105
sepp2k Avatar answered Jan 02 '26 10:01

sepp2k


If C contains a pointer to something, you pretty much always need to implement operator=. In your case it would have this signature

class C
{    
    public:
    void operator=(const C& rhs)
    {
        // For each member in rhs, copy it to ourselves
    } 
    // Your other member variables and methods go here...
};
like image 20
Tom Leys Avatar answered Jan 02 '26 08:01

Tom Leys



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!