How can a base class satisfy the definition of a parent's pure virtual function using another parent's function
I am extending an existing C++ project. I have a base class that derives from two parent classes. One of the parents has a pure virtual function. I want that pure virtual function to be defined by a function implemented in the other parent.
So, I want another开发者_C百科 parent to satisfy the base class's obligation to define a parent's pure virtual function. I have tried two approaches, both have lead to compiler errors.
Any ideas?Here is a C++ program demonstrating my first idea, hoping the compiler would just use base2
's definition of vfunc()
.
// This is my first approach, hoping the parent base2 of derived would satisfy the need to define
// base1's pure virtual vfunc.
class base1 {
public:
virtual int vfunc() = 0;
};
class base2 {
public:
int vfunc() { return 0;} //defined
};
class derived : public base1, public base2 {
public:
//empty
};
int main()
{
derived d;
base1 & b1 = d;
int result = b1.vfunc();
return result;
}
The compiler reports that derived
is still an abstract class:
$ gcc a.cc
a.cc: In function ‘int main()’:
a.cc:26: error: cannot declare variable ‘d’ to be of abstract type ‘derived’
a.cc:18: note: because the following virtual functions are pure within ‘derived’:
a.cc:7: note: virtual int base1::vfunc()
Here is my second attempt:
// This is my second attempt, defining a vfunc in the derived class that calls the other parent.
class base1 {
public:
virtual int vfunc() = 0;
};
class base2 {
public:
int vfunc() { return 0; } // defined
};
class derived : public base1, public base2 {
public:
int vfunc() { return base2::vfunc(); } // call the other parent's vfunc
};
int main()
{
derived d;
base1 & b1 = d;
int result = b1.vfunc();
return result;
}
I actually expected this to do it for me, but instead the linker is giving me a bunch of vtable errors that I do not understand: ( Mac OS 10.6, gcc 4.2.1 )
$ gcc inheritance_tester.cc
Undefined symbols:
"vtable for __cxxabiv1::__vmi_class_type_info", referenced from:
typeinfo for derivedin ccmeHq8C.o
"___cxa_pure_virtual", referenced from:
vtable for base1in ccmeHq8C.o
"___gxx_personality_v0", referenced from:
_main in ccmeHq8C.o
base2::vfunc() in ccmeHq8C.o
derived::vfunc() in ccmeHq8C.o
base1::base1() in ccmeHq8C.o
base2::base2() in ccmeHq8C.o
derived::derived()in ccmeHq8C.o
CIE in ccmeHq8C.o
"vtable for __cxxabiv1::__class_type_info", referenced from:
typeinfo for base1in ccmeHq8C.o
typeinfo for base2in ccmeHq8C.o
ld: symbol(s) not found
You need to override vfunc
from base1
. You can do it as follows:
class derived : public base1, public base2 {
public:
using base1::vfunc;
int vfunc() { return base2::vfunc(); } // call the other parent's vfunc
};
Your second piece of code is fine, you're just not compiling it correctly. You need to compile with g++, not gcc. When you compile with g++, it automatically links in the C++ runtime libraries; when you compile with gcc, it does not. You can also manually add them yourself:
# Option 1: compile with g++
g++ inheritance_tester.cc
# Option 2: compile with gcc and link with the C++ standard libraries
gcc inheritancet_test.cc -lstdc++
This modified version of derived
worked for me on Visual C++. Implication to me is that you have to disambiguate the two inherited vfunc()
s explicitly.
class base1 {
public:
virtual int vfunc() = 0;
};
class base2 {
public:
int vfunc() { return 0;} //defined
};
class derived : public base1, public base2 {
public:
int base1::vfunc() { return base2::vfunc(); } // call the other parent's vfunc
};
int main()
{
derived d;
base1 & b1 = d;
int result = b1.vfunc();
return result;
}
精彩评论