为什么我不能使用继承来实现C++中的接口?
Why can't I use inheritance to implement an interface in C++?
可能的重复项:
在父类中实现抽象类
成员 为什么C++不允许基类实现派生类的继承接口?
考虑这些对象:
struct A
{
virtual void foo() = 0;
};
struct B
{
void foo() { /* neat implementation */ }
};
我想知道为什么 --编译器明智 - 以下对象被认为是抽象的:
struct C : B, A
{
using B::foo; // I tried my best to make the compiler happy
};
编译器不允许我这样做:
A* a = new C;
Visual Studio 2010 说:
'C' : 由于以下成员而无法实例化抽象类: 'void A::foo(void)' : 是抽象的 : 参见 'A::foo' 的声明
G++ 4.6.3 说:
无法分配抽象类型"C"的对象,因为以下虚函数在"C"中是纯的:虚拟空 A::foo()
我想这在 C# 中是允许的,但我不知道所涉及的 mecanism——我只是好奇。
不幸的是,这并不能完全满足您的要求。
using
指令只是将一些名称纳入其使用的范围。 virtual
方法都需要重写,并且仅引入名称不被视为重写。
事情的真相是,C++并不直接支持授权。将名称明确纳入范围只是略有转折。
struct B
正在实现一个恰好被称为foo
并且不带参数的函数。该功能显然与A::foo
完全无关。所以当struct C
同时派生自A
和B
时,它最终继承了:
- 为
A::foo
提供实现的责任 - 与
A::foo
具有相同名称和签名的方法B::foo
,但与它没有任何关系
我认为问题很明显。您正在尝试将A
用作 C# interface
的等效项,但无法在C++中表达该概念。
现在 using
指令在这里也无济于事,因为它所做的只是将B::foo
带入C
的范围,这意味着它告诉编译器它应该考虑B::foo
作为解析名称的候选者foo
当后者在类 C
中遇到时。不幸的是,这也与实现纯虚拟方法的责任无关。
要解决这个问题,你需要在 C 中实现你自己的foo()
并显式调用 B 函数——有效地将 A::foo 转发到 C 中的 B::foo:
struct C : B, A
{
virtual void foo() {
// Override A::foo by forwarding to B::foo:
B::foo();
}
};
这在某种程度上是有意义的——A::foo() 和 B::foo() 之间没有内在的关系——你必须在 C 中明确地建立一个。
我想这在 C# 中是允许
的
C++不是 C#。
virtual void foo()
和void foo()
是两种不同的方法。
当您从 A 和 B 派生时,您可以访问两种方法:virtual A::foo
和非虚拟B::foo
。virtual A::foo
是抽象的。因此编译器错误。
- C++核心准则 C35 对于接口类"A base class destructor should be either public and virtual, or protected and nonv
- Visual C++GC接口如何启用它以及要包含哪个库
- Windows.h与GLFW.h的接口
- 当字段可以为null时,如何使用C++接口在Avro中写入数据
- 提供与TMP和SFINAE的通用接口
- 为重写std::exception的库生成swig接口时出错
- 内联如何影响模块接口中的成员函数
- COM 接口 c# 封送数组数组
- 如何在 SCIP C++ 接口中获取 MILP 约束矩阵中的系数值
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- 如何绑定 C++ gRPC 客户端的网络接口
- 模板化接口 - 创建一个泛型模板类以返回任何容器
- 如何从实现接口的模板化类实例访问结构
- 带有进度表的 curl 多接口程序
- 设计帮助 - 为不同类型的消息处理通用接口的设计模式
- 我可以在具有一个标头和一个接口的 cpp 文件中有多个嵌入吗?
- 类接口,可以创建N个方法
- 类具有相同的接口,但参数的类型不同
- 如何与 Cheerp/js 中的 extern 变量接口?
- 如何使用现代 CMake 安装捆绑的接口依赖项?