多重继承:无法实例化抽象 class
Multiple inheritance: cannot instantiate abstract class
我有这个:
class Base {
public:
Base() {};
virtual ~Base() = default;
virtual void Draw() = 0;
};
class Derived_1 {
public:
Derived_1() {};
void Draw() { std::cout << "Draw()" << std::endl; };
};
class Derived_2 : public Base, public Derived_1 {
public:
Derived_2() {};
~Derived_2() {};
//void Draw() { Derived_1::Draw(); }; <<<<<===--- This works well
};
class Derived_3 : public Derived_2 {
public:
Derived_3() {};
~Derived_3() {};
};
int main()
{
Base* d = new Derived_3();
d->Draw();
return 0;
}
我收到类似 "pure virtual function "Base::Draw" has no overrider" 的错误。我认为问题是 Derived_2 有两个 Draw() 函数,其中一个是虚拟的。但是,如果不在 Derived_2 class 中添加包装函数 Draw(),我不知道如何解决这个问题。可能吗?
我认为你的问题是你将 d 定义为 class “Base”,而不是 class “Derived_3”,所以即使你使用 derived_3编译器在“Base”下寻找 draw 的定义。
您有 2 个具有相同名称和参数的函数,这绝不是好事。尝试更改其中一个 Draw()
函数的名称,或者,如果您确实想要相同的名称,则使 Derived_1
继承自 Base
尽管名称和签名相似,但两个 Draw
函数是不同的。他们也可以有两个不同的名字。 Base
和 Derived_1
不相关,因此 Derived_1
的 Draw
不能覆盖 Base
的。
如果 Base::Draw
不是纯虚拟的,在 main
中对 d->Draw()
的调用将是不明确的,因为编译器不知道调用哪个绘图。
解决办法就是你注释掉的:在Derived_2
中提供一个Draw
,它将调用Derived_1
中的那个。 (此处不相关,但在 Base::Draw
不是纯虚拟的替代方案中,Derived_2::Draw
可能需要在两个基 类 中调用 Draw
函数。)
当您赋予 Derived_2
class 多重继承时(即,它派生自 Base
和 Derived_1
)你是说它继承了 both base classes.
的成员函数
在这种情况下,这意味着它有两个(不同的)Draw
成员具有相同的签名。因此,从 Base
派生的纯虚拟 Draw
函数将 而不是 被从 Derived_1
.
派生的函数覆盖
事实上,如果您按照建议使用 Derived_3* d = new Derived_3();
代替 main()
的第一行,您仍然会收到 "cannot instatiate abstract class" 错误,再加上另一个错误"amibuguous access of Draw()".
您注释掉的行,Derived_2
class 中的 void Draw() { Derived_1::Draw(); };
做了两件事:(1) 它解决了以后对 Draw()
的任何调用中的歧义一个Derived_2
class; (2) 它提供了对 Base
class.
的纯虚拟 Draw
函数的可行覆盖
我有这个:
class Base {
public:
Base() {};
virtual ~Base() = default;
virtual void Draw() = 0;
};
class Derived_1 {
public:
Derived_1() {};
void Draw() { std::cout << "Draw()" << std::endl; };
};
class Derived_2 : public Base, public Derived_1 {
public:
Derived_2() {};
~Derived_2() {};
//void Draw() { Derived_1::Draw(); }; <<<<<===--- This works well
};
class Derived_3 : public Derived_2 {
public:
Derived_3() {};
~Derived_3() {};
};
int main()
{
Base* d = new Derived_3();
d->Draw();
return 0;
}
我收到类似 "pure virtual function "Base::Draw" has no overrider" 的错误。我认为问题是 Derived_2 有两个 Draw() 函数,其中一个是虚拟的。但是,如果不在 Derived_2 class 中添加包装函数 Draw(),我不知道如何解决这个问题。可能吗?
我认为你的问题是你将 d 定义为 class “Base”,而不是 class “Derived_3”,所以即使你使用 derived_3编译器在“Base”下寻找 draw 的定义。
您有 2 个具有相同名称和参数的函数,这绝不是好事。尝试更改其中一个 Draw()
函数的名称,或者,如果您确实想要相同的名称,则使 Derived_1
继承自 Base
尽管名称和签名相似,但两个 Draw
函数是不同的。他们也可以有两个不同的名字。 Base
和 Derived_1
不相关,因此 Derived_1
的 Draw
不能覆盖 Base
的。
如果 Base::Draw
不是纯虚拟的,在 main
中对 d->Draw()
的调用将是不明确的,因为编译器不知道调用哪个绘图。
解决办法就是你注释掉的:在Derived_2
中提供一个Draw
,它将调用Derived_1
中的那个。 (此处不相关,但在 Base::Draw
不是纯虚拟的替代方案中,Derived_2::Draw
可能需要在两个基 类 中调用 Draw
函数。)
当您赋予 Derived_2
class 多重继承时(即,它派生自 Base
和 Derived_1
)你是说它继承了 both base classes.
在这种情况下,这意味着它有两个(不同的)Draw
成员具有相同的签名。因此,从 Base
派生的纯虚拟 Draw
函数将 而不是 被从 Derived_1
.
事实上,如果您按照建议使用 Derived_3* d = new Derived_3();
代替 main()
的第一行,您仍然会收到 "cannot instatiate abstract class" 错误,再加上另一个错误"amibuguous access of Draw()".
您注释掉的行,Derived_2
class 中的 void Draw() { Derived_1::Draw(); };
做了两件事:(1) 它解决了以后对 Draw()
的任何调用中的歧义一个Derived_2
class; (2) 它提供了对 Base
class.
Draw
函数的可行覆盖