T
required that T
have a clone()
member function rather than using T
's copy constructor.
Because copy constructors (or constructors of any kind) can't be declared
virtual, and the handle has to perform a dynamic-type lookup to find the proper
clone()
member function.
A
, B
, and C
are related by inheritance. Given
the following code
A * ap = new A; ap->f(); // Prints "Hello from A:f()." ap = new B; ap->f(); // Prints "Hello from A:f()." ap = new C; ap->f(); // Prints "Hello from C:f()."
write the class definitions of A, B, and C that are consistent with the code
and its documented behavior. You don't need to include the bodies of f()
,
but the prototype must be complete; also, you should assume that f()
correctly prints the name of its containing class.
The middle call to f()
indicates static-type (non-virtual) lookup, while
the third call to f()
indicates dynamic-type (virtual) lookup.
Unfortunately, the f()
is either virtual or non-virtual; it can't be
both.
A::f()
has to be virtual, otherwise C::f()
would never get called.
To prevent B::f()
from being called, leave it undefined in B
;
inheritance will provide B with A
's copy, effectively simulating
static-type lookup.
$ cat t.cc #includestruct A { virtual void f(void) const { cout << "Hello from A::f().\n"; } }; struct B : A { }; struct C : A { void f(void) const { cout << "Hello from C::f().\n"; } }; int main() { A * ap = new A; ap->f(); // Prints "Hello from A::f()." ap = new B; ap->f(); // Prints "Hello from A::f()." ap = new C; ap->f(); // Prints "Hello from C::f()." } $ g++ -o t -ansi -pedantic -Wall t.cc $ ./t Hello from A::f(). Hello from A::f(). Hello from C::f(). $
No, it's not. The problem with overloaded functions serving as template-function arguments is that it's generally impossible to tell which overloaded function is being referenced. A function serving as a parameter appears without arguments, which makes it impossible for the compiler to tell which overloaded function is being referenced. For example:
void print(const string & s) { // whatever } void print(const int i) { // whatever } templatevoid print_it(T f) { // whatever } int main() { print_it(print); // which print()? }
A
, B
, and C
be related to each other by inheritance.
Suppose each class's default constructor body contains a statement that prints a
message when when the constructor's called. If the declaration
B b;
produces the following output:
Hello from A::A(). Hello from C::C(). Hello from B::B().
describe the inheritance relations among the three classes.
Constructors are called from the top down; that is, a parent's constructor is called before the child's. The sequence of print statements given in the problem is consistent with the declarations
$ cat t.cc #includeusing std::cout; struct A { A() { cout << "Hello from A::A()\n"; } }; struct C : A { C() { cout << "Hello from C::C()\n"; } }; struct B : C { B() { cout << "Hello from B::B()\n"; } }; int main() { B b; } $ g++ -o t -ansi -pedantic -Wall t.cc t.cc: In function int main(): t.cc:17: warning: unused variable struct B b $ ./t Hello from A::A() Hello from C::C() Hello from B::B() $
This page last modified on 19 December 2001.