Re: questions about dynamic binding
On May 12, 12:13 pm, Jess <w...@hotmail.com> wrote:
I have some questions to do with dynamic binding. The example program
is:
#include<iostream>
using namespace std;
class A{
public:
virtual void f(){cout << "A::f()" << endl;}
};
class B:public A{
public:
void f(){cout << "B::f()" << endl;}
};
int main(){
B b;
A* bp = &b;
// A* bp2 = new B(*bp);
A* bp2 = new A(*bp);
bp2->f();
bp->f();
return 0;
}
As I expected "bp->f()" calls B's f(). However, "bp2->f()" calls A's
f().
That's because, as written, bp2 points to an A.
Is it because of the "new A", which only copies the A's part of
"*bp" object, or is it because of the behaviour of the synthesized
copy constructor of A? If it is the latter, then can I create a B
object by defining my own copy constructor for A?
It's because in the expression "new A", you tell the compiler
explicitly to create an A object. All of the rest follows;
there is no way that the expression "new A" can create anything
other than an A.
It's a classical case of the compiler doing what you told it
to, and not what you wanted. Otherwise known as "you asked for
it, you got it."
In addition, the statement that is commented out produced compiler
error. It says "no matching function for call to 'B::B(A&)'". Can't
compiler find out *bp is in fact a B object?
No, because it might not be. Virtuality only works on the
object the function is called on. Since no object exists when
the constructor is called, it cannot be virtual, and of course,
virtuality never works on arguments.
The classical solution here is to provide a clone function in
the base class, i.e.:
class A
{
public:
A* clone() const
{
A* result = doClone() ;
assert( typeid( *result ) == typeid( *this ) ) ;
return result ;
}
private:
virtual A* doClone() const
// Except that usually, this will be pure virtual.
// It's fairly rare to have virtual functions in a
// base class which aren't pure virtual.
{
return new A( *this ) ;
}
} ;
class B
{
private:
virtual A* doClone() const
{
return new B( *this ) ;
}
} ;
When you want to copy, you use clone, rather than new. (I've
also occasionally found it useful to have a function "another",
along the same lines as clone(), but using default construction
rather than copy.)
--
James Kanze (Gabi Software) email: james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34