3

我正在扩展一个现有的 C++ 项目。我有一个派生自两个父类的基类。其中一个父母有一个纯虚函数。我希望该纯虚函数由另一个父级中实现的函数定义。

所以,我希望另一个父类满足基类定义父类纯虚函数的义务。我尝试了两种方法,都导致编译器错误。
有任何想法吗?

这是一个展示我的第一个想法的 C++ 程序,希望编译器只base2使用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;
}

编译器报告它derived仍然是一个抽象类:

$ 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()

这是我的第二次尝试:

// 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;
} 

我实际上希望这能为我做这件事,但链接器却给了我一堆我不明白的 vtable 错误:(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
4

3 回答 3

3

您需要从vfunc覆盖base1。你可以这样做:

class derived : public base1, public base2 {
public:
 using base1::vfunc;
 int vfunc() { return base2::vfunc(); } // call the other parent's vfunc
};
于 2010-09-15T20:14:27.157 回答
2

你的第二段代码很好,你只是没有正确编译它。您需要使用 g++ 编译,而不是 gcc。当你用 g++ 编译时,它会自动链接到 C++ 运行时库中;当你用 gcc 编译时,它不会。您也可以自己手动添加它们:

# 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++
于 2010-09-15T20:30:53.487 回答
0

这个修改后的版本derived在 Visual C++ 上为我工作。对我的暗示是,您必须vfunc()明确消除两个继承的 s 的歧义。

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;
}
于 2010-09-15T20:16:58.817 回答