-
June 2nd, 2013, 09:12 AM
#1
operator overloading and inheritance
Hi,
So i am having troubles with operator overloading in inherited class. Basically, it doesnt work. Consider this:
Code:
class A
{
public:
A()
{
x=0;
z= new int;
}
~A()
{
delete z;
}
int x;
int* z;
A& operator=(A& a)
{
x = a.x;
z = new int(*a.z);
return *this;
}
};
class B : public A
{
public:
B(){y=0;}
B(B& b, int dummy) //pseudo-assignment constructor
{
operator=(b);
}
int y;
B& operator=(B& b)
{
y = b.y;
A::operator=(b);
return *this;
}
};
void somefunc(B& b)
{
/*
some how the copy constructor of a is improperly executed - the pointer is copied over, not re-created.
As a result, the destructors crashes due to double-free.
*/
B bb = b; //doesnt work
B bbb(b); //doesnt work
B bbbb(b, 0); //works
}
Above code shows the problem well. The "official" copy-constructor wont work - it copies over the pointer directly, and doesnt create a new one as it should. However, if i provide my own pseudo-copy-constructor that works.
But ofcourse it's just a cheap work around - and wont actually work in real code (STL).
What's wrong? Strikes me as very odd...
compiler is VS2008SP1.
edit:
I have added a proper example, sorry.
Last edited by tuli; June 2nd, 2013 at 10:00 AM.
Reason: foramtting
-
June 2nd, 2013, 09:25 AM
#2
Re: operator overloading and inheritance
It would help if you indent your code properly and explained how does the relevant code not work. A simple and short program that we can compile and run, with the expected output and your actual output, would be excellent.
Originally Posted by tuli
The "official" copy-constructor wont work (as far as i see, it calls B's default constructor instead).
You are aware that you can invoke the base class copy constructor in the initialisation list of the copy constructor of a derived class, right?
Furthermore, it is more conventional to implement the copy assignment operator using the copy constructor (and maybe the destructor and a swap function) rather than implement the copy constructor using the copy assignment operator.
-
June 2nd, 2013, 10:02 AM
#3
Re: operator overloading and inheritance
You are aware that you can invoke the base class copy constructor in the initialisation list of the copy constructor of a derived class, right?
yes.
Furthermore, it is more conventional ...
thanks, i'll consider that next time.
--
I have added a better example. It now compiles and crashes as expected.
-
June 2nd, 2013, 10:50 AM
#4
Re: operator overloading and inheritance
Originally Posted by tuli
Hi,
So i am having troubles with operator overloading in inherited class. Basically, it doesnt work.
Code:
A& operator=(A& a)
{
x = a.x;
z = new int(*a.z);
return *this;
}
The assignment operator assigns to an existing object. So what happens if "z" were already allocated in the existing object? You now have a memory leak since you never called "delete".
I would highly suggest you not mix up assignment operators with copy construction. If anything, both functions can call a common function to do the internal copying, but you shouldn't call the assignment operator from the copy constructor. Doing so leads to confusing code, both to you and anyone trying to decipher what is attempting to be done.
First implement the copy constructor, assuming that there is no such thing as an assignment operator. Next, implement the assignment operator, assuming there is no thing as a copy constructor. Now take those two functions you implemented, factor out the common code, and place that common code into an internal "copy_elements" or similar function. Then change your assignment and copy functions to call this common function.
Regards,
Paul McKenzie
Last edited by Paul McKenzie; June 2nd, 2013 at 10:53 AM.
-
June 2nd, 2013, 11:04 AM
#5
Re: operator overloading and inheritance
Where is the copy constructor for class A?
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
June 2nd, 2013, 11:18 AM
#6
Re: operator overloading and inheritance
To follow up on 2kaud's point:
Code:
B(B& b, int dummy) //pseudo-assignment constructor
Don't do this. Write a real, bonafide copy constructor, not a fake one.
If you implement this function, then you are implementing the copy constructor.
Regards,
Paul McKenzie
-
June 2nd, 2013, 11:33 AM
#7
Re: operator overloading and inheritance
Originally Posted by tuli
I have added a proper example, sorry.
As 2kaud alluded to in post #5, for this new example, you fail to follow the rule of three, i.e., whenever you define the copy constructor, the copy assignment operator or the destructor, you should define all three. (Though sometimes you might define the destructor merely to declare it virtual, and other times you might disable copying instead.)
Additionally, unless you have special reasons for doing otherwise, the parameter of the copy assignment operator should be a const reference, not a non-const reference.
Originally Posted by Paul McKenzie
I would highly suggest you not mix up assignment operators with copy construction. If anything, both functions can call a common function to do the internal copying, but you shouldn't call the assignment operator from the copy constructor. Doing so leads to confusing code, both to you and anyone trying to decipher what is attempting to be done.
First implement the copy constructor, assuming that there is no such thing as an assignment operator. Next, implement the assignment operator, assuming there is no thing as a copy constructor. Now take those two functions you implemented, factor out the common code, and place that common code into an internal "copy_elements" or similar function. Then change your assignment and copy functions to call this common function.
Not quite: before the advent of move constructors, it would be acceptable or even recommended to use the copy/swap idiom to implement the copy assignment operator. This would mean the usage of the copy constructor under the assumption that the copy constructor for A had been defined correctly. But yes, one should implement the copy constructor "assuming that there is no such thing as an assignment operator".
-
June 3rd, 2013, 03:49 AM
#8
Re: operator overloading and inheritance
Alright, following that "rule of three" and giving both A and B independent copy constructors and assignment operators works fine! Thanks!
I ignored const-correctness and memory leaks to keep the example simple.
Though sometimes, when i step into the an ssignment operator like B bb = b;, i end up in the copy constructor, not the assignment operator. How so?
-
June 3rd, 2013, 04:34 AM
#9
Re: operator overloading and inheritance
Originally Posted by tuli
Though sometimes, when i step into the an ssignment operator like B bb = b;, i end up in the copy constructor, not the assignment operator. How so?
You are constructing an object named bb, so why would you expect an assignment operator to be invoked?
-
June 3rd, 2013, 04:58 AM
#10
Re: operator overloading and inheritance
Originally Posted by tuli
Though sometimes, when i step into the an assignment operator like B bb = b;, i end up in the copy constructor, not the assignment operator. How so?
That does not call the assignment operator. You are constructing a brand new object, bb, from an existing object, therefore the copy constructor is invoked.
Regards,
Paul McKenzie
-
June 3rd, 2013, 09:18 AM
#11
Re: operator overloading and inheritance
Originally Posted by tuli
I ignored const-correctness and memory leaks to keep the example simple.
"Everything should be made as simple as possible, but not simpler." - Albert Einstein
Const-correctness and avoiding memory leaks are mandatory for a working example.
Cheers, D Drmmr
Please put [code][/code] tags around your code to preserve indentation and make it more readable.
As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky
-
June 3rd, 2013, 03:54 PM
#12
Re: operator overloading and inheritance
@McKenzy
Suppose that makes sense...
@D_Drummer
Alright, i'll consider it next time i'll bother you guys.
Thanks for the help!
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|