如何声明必须实现而非虚函数
How to declare function which must be implemented and not virtual?
我使用class来声明接口。我只想定义方法签名。此方法必须在任何非抽象子类中实现。我不需要方法是虚拟的。这是c#的默认行为BTW(我来自c#/Java世界)
然而在c++中这似乎是不可能的。我要么以常规方式声明方法
void Foo::Method()
,然后不强制实现它或将方法声明为"纯虚拟"
void virtual Foo::Method() = 0;
和method变成了虚拟的,但是我想避免这种情况,以节省一点性能。
似乎我也想要这样的东西
void Foo::Method() = 0;
但是这会导致编译错误
如果你打算从模板代码中使用派生类,即编译时多态性,那么你只需要记录预期的签名
如果使用的函数没有实现,那么使用派生类的代码将无法编译和链接
否则,对于运行时多态性,它需要是虚拟的,否则它将不会被称为
我相信你可能会对c#版本的工作方式感到困惑:
class A {
public void NonVirt() { Console.Out.WriteLine("A:NonVirt"); }
public virtual void Virt() { Console.Out.WriteLine("A:Virt"); }
}
class B : A {
public void NonVirt() { Console.Out.WriteLine("B:NonVirt"); }
public override void Virt() { Console.Out.WriteLine("B:Virt"); }
}
class Program {
static void Main(string[] args) {
A x = new B();
x.NonVirt();
x.Virt();
}
}
这将输出
A:NonVirt
B:Virt
因此,即使在c#中,如果你想调用派生实现,你也需要将方法设为virtual。
如果方法必须在所有非抽象子类中实现,这意味着您需要通过基类指针调用它们。这反过来意味着你需要使它们成为虚拟的,就像在c#中一样(也可能在Java中,但我不确定)
顺便说一句,在现代cpu上,虚拟调用的价格是几纳秒,所以我不确定它是否值得,但让我们说它是值得的。
如果想避免虚调用的开销,应该通过模板使用编译时多态性
c++中没有接口的概念。实现目标的唯一方法是创建一个定义为virtual
和= 0
的基类,所有的方法必须在子类中实际定义。
class IBase {
// ...
virtual void f1() = 0;
// ....
}
如果所有方法都像f1
那样定义,该类将是虚纯的,这是您可以获得的最接近接口的。
在Java中接口的概念有点像实现它的类的契约。编译器通过检查实现者的内容来执行契约的约束。这种契约或显式结构子类型的概念在c++中并不正式存在。
然而,你可以通过定义一个模板来手动验证这些约束是否得到尊重,这个模板将期望一个类的参数具有定义的方法或属性,并在要验证的类上使用该模板。
- 在命名空间内部还是外部实现 c++ 函数?
- 如何在C++中实现函数(f)(x)(y, z)(g)(r)
- 如何在C++中实现函数上的二叉搜索?
- 键按下事件错误 Qt 实现函数时
- 在子类之外实现函数导致未知错误
- 通过模板滥用实现函数式C++
- C++,实现函数"int next(std::string param)"时出现奇怪的编译器错误
- 我正在尝试创建自己的 strcat() 函数,而不是使用库实现函数<cstring>
- 如果未实现函数,则在链接时启用错误
- 用函数参数实现c++函数指针
- 如何在Android SDK中调用和实现C++函数
- 在 C++ RCPP 中实现 R 函数
- 实现函数模板填充多维对象
- 类的层次结构,试图在基本级别实现函数
- 用c++实现函数对象的自动检测类型
- 用shared_ptrs实现函数模板的C++实例化
- 在类中实现函数导致错误:成员引用基类型'ifstream (string)'不是结构或联合
- 用c++实现S函数.生成错误
- 引用可以用于实现函数重写吗
- 如何在c++中实现函数超时