Is-没有虚函数 c++ 的关系

Is-a relationship without virtual functions c++

本文关键字:c++ 关系 函数 Is-      更新时间:2023-10-16

我找不到没有虚函数的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并且可以很好地绑定到Base指针。不可能说它是否满足 Liskov 替换原理,因为我们不知道你的类的不变量。

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

此外,如果没有人应该从Derived派生,则将其标记为final,自 C++11 起可用

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

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