copy constructor

Apr 18, 2008 at 5:31am
is the below code is valid
class test
{
int a;
public:
test()
{
a=o;
cout<<a;
}
test(int a)
{
a=a;
cout<<a;
}
test(test &t) //copy constructor
{
a=t.a;
}
};
void main()
{
test t;
test t(5);
test t1=t; //is this a valid code
} can a parameterized constructor can be assigned to and newly created object
how to do it
Apr 18, 2008 at 8:03am
It is not valid
1)
1
2
3
4
5
test(int a)
{
a=a;
cout<<a;
}

this code is wrong, Compiler does not which variable a is which
2)
1
2
3
test t;
test t(5);
test t1=t; //is this a valid code 

don't declare same variable twice;

I modified your code. This code should copy the constructor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
class test
{
public:
	int a;
	test()
	{
		a=0;
		cout<<a;
	}
	test(int pa)
	{
		a = pa;
		cout<<a;
	}
	test(test &t) //copy constructor
	{
		a=t.a;
		cout<<"\n t.a"<< t.a;
	}
};
void main()
{
	test t(5);
	cout<<"\n"<<t.a;
	test t1(t);
	cout<<"\n"<<t1.a;
	getchar();
}


Apr 18, 2008 at 8:05am
Please use the 'Insert Code' button, and put your fomatted code betweeen the "[ code ]" and "[ / code ]" tags to make it easier for everyone to read:-)

You need to make a couple of changes on thsi one.
The basic constructor
1
2
3
4
5
test(int a)
{
    a=a;
    cout<<a;
}

needs to have a different parameter name.
Currently it does NOT set the private variable a as the parameter a is considered more local in scope.
Change to
1
2
3
4
5
test(int b)
{
    a=b;
    cout<<a;
}

and it works fine.

Note that this sort of error, where a parameter name overrides an atribute name, can be very difficult to find in a large project.

Secondly you need to change the varaible name for the test of the parameterised constructor as you alreadsy have a vaiable t.

try
1
2
3
4
5
6
void main()
{
    test t;
    test t2(5);
    test t1=t2; 
}


I have added an overload of the operator << to allow you to output the value of a in an instance of test so you can see it all working.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
using namespace std;

class test
{
	int a;
public:
	test()
	{
		a=0;
		cout<<a;
	}
	test(int b)
	{
		a=b;
		cout<<a;
	}
	test(test &t) //copy constructor
	{
		a=t.a;
		cout << "Copy! ";
	}
	friend ostream& operator<<(ostream & os,const test &t);
};

ostream& operator<<(ostream & os,const test &t)
{
	os << t.a;
	return os;
};

int main()
{
	test t;
	cout << t << endl;
	test t1(5);
	cout << t1 << endl;
	test t2=t1; 
	cout << t2 << endl;
	test t3(t2);
	cout << t3 << endl;


	system("pause");
	return 0;
}


You can also change the parameterised constructor back to your original version in the above to see the effect of it hiding the private variable.
Apr 18, 2008 at 8:24am
>> The basic constructor 1 [...] needs to have a different parameter name.
Although a good point, it's not entirely true. There are two ways to fix this without changing the parameter name:

1. With an initialize list:
1
2
test(int a) : a(a) // Initialize the member variable a with the value of the parameter a
{}


2. Explicitly setting the member variable using 'this':
1
2
3
4
test(int a)
{
  this->a = a; // Assign the value of the parameter a to the member variable a
}


BTW: I don't think 'b' was a good suggestion for the parameter containing the initial value of 'a'. The name should reflect the name of the member variable:
1
2
3
test(int _a) // It's common to use an underscore
test(int initial_a)
test(int a_value)
Last edited on Apr 18, 2008 at 8:27am
Apr 18, 2008 at 9:10am
Yes, you can do extra work to get arround it, but it's simpler just to use a different parameter name!

'b' vs '_a', etc.
Agreed - but then this is logically extended to avoid 'a' as an attribute name in the first place...
The point was to have something simple to demonstrate the change required:-)
Apr 18, 2008 at 9:17am
>> but then this is logically extended to avoid 'a' as an attribute name in the first place...

Of course. I was about to add that, but I decided not to.
Topic archived. No new replies allowed.