如何声明必须实现的功能而不是虚拟功能?

时间:2013-03-13 18:01:33

标签: c++ interface low-latency

我正在使用类来声明接口。我只想定义方法签名。此方法必须在任何非抽象子类中实现。我不需要方法是虚拟的。这是C#BTW中的默认行为(我来自C#/ Java世界)

然而,在C ++中它似乎是不可能的。我要么以常规方式声明方法

void Foo::Method()

然后不是必须实现它或将方法声明为“纯虚拟”

void virtual Foo::Method() = 0;

然后方法变为虚拟,但我想避免这种情况以节省性能。

似乎我想要有类似的东西

void Foo::Method() = 0;

但那将是compilation error

3 个答案:

答案 0 :(得分:3)

如果你打算从模板代码中使用派生类,即编译时多态,那么你只需要记录预期的签名

如果未实现使用的函数,使用派生类的代码将无法编译和链接

否则,对于运行时多态性,它需要是虚拟的,否则不会被称为

答案 1 :(得分:2)

我相信您可能会对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#中,如果要调用派生实现,也需要将方法设为虚拟。

如果必须在所有非抽象子类中实现方法,这意味着您需要通过基类指针调用它们。这反过来意味着你需要将它们设置为虚拟,与C#相同(可能在Java中,但我不确定)

顺便说一下,现代CPU的虚拟通话价格只有几纳秒,所以我不确定它是否值得,但可以说它是。

如果要避免虚拟调用的成本,则应通过模板使用编译时多态性

答案 2 :(得分:0)

C ++中没有接口的概念。实现目标的唯一方法是创建一个基类,定义为virtual= 0所有必须在子类中实际定义的方法。

class IBase {
      // ...
        virtual void f1() = 0;
      // ....
}

如果所有方法都定义为f1,那么该类将是虚拟纯的,这是最接近您可以获得的接口。

Java中的接口概念有点像实现它的类的契约。编译器通过检查实现者的内容来强制执行合同约束。契约或显式结构子类型的概念在C ++中不是正式存在的。

但是,您可以通过定义一个模板来手动验证是否遵守了这些约束,该模板将期望作为具有已定义方法或属性的类的参数,并在要验证的类上使用该模板。我认为这可以被视为一种单元测试形式。