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.
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.
Quote:
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.
Re: operator overloading and inheritance
Quote:
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.
Quote:
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. :)
Re: operator overloading and inheritance
Quote:
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
Re: operator overloading and inheritance
Where is the copy constructor for class A?
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
Re: operator overloading and inheritance
Quote:
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.
Quote:
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".
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?
Re: operator overloading and inheritance
Quote:
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?
Re: operator overloading and inheritance
Quote:
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
Re: operator overloading and inheritance
Quote:
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.
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!