Copy constructors and operator=
-
Ack. Just got caught out by a classic and feel like a right fool. I'd written a unit test for testing object equality via a class's
operator=
. However, the test was succeeding, even though it should of failed, as I knew for sure that some class members were not being assigned. After some head scratching I looked at the test again:// Test operator=
foo a;
...
foo b = a;
BOOST_CHECK(b == a);I knew that
operator==
was correct, so what was my schoolboy howler? I'd forgotten thatfoo b = a
callsfoo
's copy constructor and notoperator=
. In this case I hadn't supplied a copy constructor, so the compiler obliged and created one for me, which, IIRC, does bitwise assignment, which meant the test succeeded. I changed the code to:// Test operator=
foo a;
...
foo b;
b = a;
BOOST_CHECK(b == a);And it worked as expected. D'oh. Moral: If you are going to override
operator=
you should probably add a copy constructor and make sure both are consistent!
Kicking squealing Gucci little piggy.
-
Ack. Just got caught out by a classic and feel like a right fool. I'd written a unit test for testing object equality via a class's
operator=
. However, the test was succeeding, even though it should of failed, as I knew for sure that some class members were not being assigned. After some head scratching I looked at the test again:// Test operator=
foo a;
...
foo b = a;
BOOST_CHECK(b == a);I knew that
operator==
was correct, so what was my schoolboy howler? I'd forgotten thatfoo b = a
callsfoo
's copy constructor and notoperator=
. In this case I hadn't supplied a copy constructor, so the compiler obliged and created one for me, which, IIRC, does bitwise assignment, which meant the test succeeded. I changed the code to:// Test operator=
foo a;
...
foo b;
b = a;
BOOST_CHECK(b == a);And it worked as expected. D'oh. Moral: If you are going to override
operator=
you should probably add a copy constructor and make sure both are consistent!
Kicking squealing Gucci little piggy.
I also faced similar problem many times. I learnt it the hard way toalways start my C++ class with private copy constructors and assignment operators with no implementations and make them public and add implementation later only when I need them.
Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. -Brian Kernighan
-
Ack. Just got caught out by a classic and feel like a right fool. I'd written a unit test for testing object equality via a class's
operator=
. However, the test was succeeding, even though it should of failed, as I knew for sure that some class members were not being assigned. After some head scratching I looked at the test again:// Test operator=
foo a;
...
foo b = a;
BOOST_CHECK(b == a);I knew that
operator==
was correct, so what was my schoolboy howler? I'd forgotten thatfoo b = a
callsfoo
's copy constructor and notoperator=
. In this case I hadn't supplied a copy constructor, so the compiler obliged and created one for me, which, IIRC, does bitwise assignment, which meant the test succeeded. I changed the code to:// Test operator=
foo a;
...
foo b;
b = a;
BOOST_CHECK(b == a);And it worked as expected. D'oh. Moral: If you are going to override
operator=
you should probably add a copy constructor and make sure both are consistent!
Kicking squealing Gucci little piggy.
Rob Caldecott wrote:
In this case I hadn't supplied a copy constructor, so the compiler obliged and created one for me, which, IIRC, does bitwise assignment
IIRC, I think it does memberwise copy construction, recursively calling each member's copy constructor.
Rob Caldecott wrote:
Moral: If you are going to override operator= you should probably add a copy constructor and make sure both are consistent!
Even better is the "Rule of Three": If you need any one out of {destructor, assignment operator, copy constructor} then you probably need all three!
-- Marcus Kwok
-
Ack. Just got caught out by a classic and feel like a right fool. I'd written a unit test for testing object equality via a class's
operator=
. However, the test was succeeding, even though it should of failed, as I knew for sure that some class members were not being assigned. After some head scratching I looked at the test again:// Test operator=
foo a;
...
foo b = a;
BOOST_CHECK(b == a);I knew that
operator==
was correct, so what was my schoolboy howler? I'd forgotten thatfoo b = a
callsfoo
's copy constructor and notoperator=
. In this case I hadn't supplied a copy constructor, so the compiler obliged and created one for me, which, IIRC, does bitwise assignment, which meant the test succeeded. I changed the code to:// Test operator=
foo a;
...
foo b;
b = a;
BOOST_CHECK(b == a);And it worked as expected. D'oh. Moral: If you are going to override
operator=
you should probably add a copy constructor and make sure both are consistent!
Kicking squealing Gucci little piggy.
I'm not sure why, but the statement
foo b = a;
is referred to as an initializer or initialization statement instead of an assignment statement. I'm sure there is a specific need that this difference addresses, but it's lost on me. :-O
Chris Meech I am Canadian. [heard in a local bar] Nobody likes jerks. [espeir] The zen of the soapbox is hard to attain...[Jörgen Sigvardsson] I wish I could remember what it was like to only have a short term memory.[David Kentley]
-
I'm not sure why, but the statement
foo b = a;
is referred to as an initializer or initialization statement instead of an assignment statement. I'm sure there is a specific need that this difference addresses, but it's lost on me. :-O
Chris Meech I am Canadian. [heard in a local bar] Nobody likes jerks. [espeir] The zen of the soapbox is hard to attain...[Jörgen Sigvardsson] I wish I could remember what it was like to only have a short term memory.[David Kentley]
Chris Meech wrote:
I'm sure there is a specific need that this difference addresses, but it's lost on me.
Efficiency. If it was to use the assignment operation, it would first have to create and initialize b (using the default constructor) and then call the assignment operator (basically, doing the assignments twice). By using the copy-constructor, it avoids initialization in the default constructor.
If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac
-
Rob Caldecott wrote:
In this case I hadn't supplied a copy constructor, so the compiler obliged and created one for me, which, IIRC, does bitwise assignment
IIRC, I think it does memberwise copy construction, recursively calling each member's copy constructor.
Rob Caldecott wrote:
Moral: If you are going to override operator= you should probably add a copy constructor and make sure both are consistent!
Even better is the "Rule of Three": If you need any one out of {destructor, assignment operator, copy constructor} then you probably need all three!
-- Marcus Kwok
ricecake wrote:
Even better is the "Rule of Three": If you need any one out of {destructor, assignment operator, copy constructor} then you probably need all three!
True. Although modern C++ techniques tend to reduce it to The rule of two[^]
-
ricecake wrote:
Even better is the "Rule of Three": If you need any one out of {destructor, assignment operator, copy constructor} then you probably need all three!
True. Although modern C++ techniques tend to reduce it to The rule of two[^]
-
I'm not sure why, but the statement
foo b = a;
is referred to as an initializer or initialization statement instead of an assignment statement. I'm sure there is a specific need that this difference addresses, but it's lost on me. :-O
Chris Meech I am Canadian. [heard in a local bar] Nobody likes jerks. [espeir] The zen of the soapbox is hard to attain...[Jörgen Sigvardsson] I wish I could remember what it was like to only have a short term memory.[David Kentley]
In:
foo a;
foo b = a;the second line is equivalent to:
foo b(a);
That is, construct
b
as a copy ofa
. That's why the copy ctor is called.--Mike-- Visual C++ MVP :cool: LINKS~! Ericahist | PimpFish | CP SearchBar v3.0 | C++ Forum FAQ