Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding and using a copy assignment constructor

I'm trying to understand how the copy assignment constructor works in c++. I've only worked with java so i'm really out of my waters here. I've read and seen that it's a good practice to return a reference but i don't get how i should do that. I wrote this small program to test the concept:

main.cpp:

#include <iostream>
#include "test.h"

using namespace std;

int main() {
    Test t1,t2;
    t1.setAge(10);
    t1.setId('a');
    t2.setAge(20);
    t2.setId('b');

    cout << "T2 (before) : " << t2.getAge() << t2.getID() << "\n";

    t2 = t1; // calls assignment operator, same as t2.operator=(t1)

    cout << "T2 (assignment operator called) : " << t2.getAge() << t2.getID() << "\n";

    Test t3 = t1; // copy constr, same as Test t3(t1)

    cout << "T3 (copy constructor using T1) : " << t3.getAge() << t3.getID() << "\n";

    return 1;
}

test.h:

class Test {
    int age;
    char id;

    public:
        Test(){};
        Test(const Test& t); // copy
        Test& operator=(const Test& obj); // copy assign
        ~Test();
        void setAge(int a);
        void setId(char i);
        int getAge() const {return age;};
        char getID() const {return id;};
};

test.cpp:

#include "test.h"

void Test::setAge(int a) {
    age = a;
}

void Test::setId(char i) {
    id = i;
}

Test::Test(const Test& t) {
    age = t.getAge();
    id = t.getID();
}

Test& Test::operator=(const Test& t) {

}

Test::~Test() {};

I can't seem to understand what i should be putting inside operator=(). I've seen people returning *this but that from what i read is just a reference to the object itself (on the left of the =), right? I then thought about returning a copy of the const Test& t object but then there would be no point to using this constructor right? What do i return and why?

like image 685
Stelios Papamichail Avatar asked Nov 01 '25 02:11

Stelios Papamichail


1 Answers

I've read and seen that it's a good practice to return a reference but i don't get how i should do that.

How

Add

return *this;

as the last line in the function.

Test& Test::operator=(const Test& t) {
   ...
   return *this;
}

Why

As to the question of why you should return *this, the answer is that it is idiomatic.

For fundamental types, you can use things like:

int i;
i = 10;
i = someFunction();

You can use them in a chain operation.

int j = i = someFunction();

You can use them in a conditional.

if ( (i = someFunction()) != 0 ) { /* Do something */ }

You can use them in a function call.

foo((i = someFunction());

They work because i = ... evaluates to a reference to i. It's idiomatic to keep that semantic even for user defined types. You should be able to use:

Test a;
Test b;

b = a = someFunctionThatReturnsTest();

if ( (a = omeFunctionThatReturnsTest()).getAge() > 20 ) { /* Do something */ }

But Then

More importantly, you should avoid writing a destructor, a copy constructor, and a copy assignment operator for the posted class. The compiler created implementations will be sufficient for Test.

like image 93
R Sahu Avatar answered Nov 03 '25 15:11

R Sahu