【发布时间】:2020-09-16 06:51:58
【问题描述】:
我正面临我根导致此代码 sn-p 的继承层次结构错误。 l() 的定义是在模板类 Y 中定义的,我不明白为什么编译器会发现它模棱两可。Class Z ptr_ 指向具有 l() 定义的 Y 类对象,这不是应该的吗工作吗?
不幸的是,基类都是静态库的一部分,C 类是我唯一可以控制的东西。我不确定我能在这里做什么。
Error:
Line 84: Char 13: error: non-static member 'l' found in multiple base-class subobjects of type 'D':
class C -> class A -> class D
class C -> class B -> class D
ptr_->l ()
Line 96: Char 15: note: in instantiation of member function 'Z<C>::~Z' requested here
Z < C > t = new Y < C > ();
^
Line 31: Char 16: note: member found by ambiguous name lookup
virtual void l () = 0;
#include <iostream>
using namespace std;
template <class T>
class Y : public T {
public:
void l() {}
void p() {}
};
class D {
public:
virtual void l() = 0;
virtual void p() = 0;
};
class A : public D {
public:
virtual void f(int a) = 0;
virtual void d() = 0;
};
class B : public D {
public:
virtual void j(string x) = 0;
virtual void d() = 0;
};
class C : public A, public B {
public:
void f(int a) override {}
void j(string x) override {}
void d() override {}
};
template <class T>
class Z {
public:
Z(T *ptr) : ptr_(ptr) {}
~Z() {
if (ptr_)
ptr_->l();
}
protected:
T *ptr_;
};
int main() {
Z<C> t = new Y<C>();
return 0;
}
【问题讨论】:
-
class C继承自class A和class B。因此,它公开了两个virtual方法l():A::l()和B::l()。因此,编译无法决定为ptr_->l();选择哪一个。使用 virtual 基类或帮助它(通过插入强制转换)来选择预期的。 -
这是因为
C通过两个不同的路径(如A::l()和B::l())继承了成员函数l()。两者都解析为D::l()的事实是无关紧要的 - 有两条不同的路径可以到达它,没有理由偏爱一条或另一条,也没有什么能阻止A或B提供自己的覆盖。修复选项(没有修复继承关系以消除歧义,这通常是更可取的)是命名您想要的(例如ptr->A::l()或ptr->B::l())或使D成为A的虚拟基础和B. -
不幸的是,基类都是静态库的一部分,C 类是我唯一可以控制的东西。我不确定我能在这里做什么。