是没有虚函数的关系c ++

时间:2017-07-27 12:49:32

标签: c++ inheritance

我无法找到没有虚函数的is-a关系的例子。以下模式可以吗?

class Base {
public:
  void doSomethingWithX() {/*implementation here*/}
protected:
  ~Base(){}
private:
   int x_;
};

class Derived : public Base {
//Add some other functionality but inherit doSomethingWithX and its implementaion
public: 
  void doSomethingWithY();
  ~Derived(); //And document that nobody should inherit further from this class.
private:
  int y_;
};

foo(Base* ptr) {
//Do something via Base interface
}

Derived d;
foo(&d);

编辑:我被要求澄清我的意思"这种模式是否正常"。 这种继承是否满足is-a关系通常需要的东西?利斯科夫替代原则等 通过指向Base的方法使用Derived对象是否安全? (或者我在这里想念一些问题)。

我问这个是因为经常写的基类析构函数应该是公共的和虚拟的,或者是受保护的和非虚拟的。但是,如果没有非虚函数,我从未遇到过公共继承的真实例子。

2 个答案:

答案 0 :(得分:1)

对于你在这里做的事情;您可以将指针传递给Derived,它可以绑定到Base的指针就好了。它不可能说它是否满足Liskov的子句原则,因为我们不知道你的类的不变量。

只要认识到没有任何虚函数,就不能使用多态。这不仅仅是简单地覆盖功能行为;您永远无法执行dynamic_cast指向Base指针Derived的指针。

此外,如果没有人应该从Derived派生,那么请将其标记为final,这是自C ++ 11以来可用的

答案 1 :(得分:0)

有两种类型的多态,都可以在C ++中实现:静态和动态。后者是您使用虚函数和指向基类的指针所获得的,其中行为是专门的,具体取决于指向的实际对象类型。 前者可以通过编写模板来实现,其中假设模板类型具有某些接口。然后编译器在编译时实例化模板时强制执行。您可以使用SFINAE和/或static_asserts提供额外的强制执行,以确保使用的类型"是"或者更确切地说,符合代码使用的模板化界面。请注意,除了上述方法之外,没有像基本接口类那样直接定义此接口的方法。

请注意,静态多态性是您在编译时获得的。在运行时没有动态选择的类型。你需要某种形式的基类。