我无法找到没有虚函数的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对象是否安全? (或者我在这里想念一些问题)。
我问这个是因为经常写的基类析构函数应该是公共的和虚拟的,或者是受保护的和非虚拟的。但是,如果没有非虚函数,我从未遇到过公共继承的真实例子。
答案 0 :(得分:1)
对于你在这里做的事情,;您可以将指针传递给Derived
,它可以绑定到Base
的指针就好了。它不可能说它是否满足Liskov的子句原则,因为我们不知道你的类的不变量。
只要认识到没有任何虚函数,就不能使用多态。这不仅仅是简单地覆盖功能行为;您永远无法执行dynamic_cast
指向Base
指针Derived
的指针。
此外,如果没有人应该从Derived
派生,那么请将其标记为final
,这是自C ++ 11以来可用的
答案 1 :(得分:0)
有两种类型的多态,都可以在C ++中实现:静态和动态。后者是您使用虚函数和指向基类的指针所获得的,其中行为是专门的,具体取决于指向的实际对象类型。 前者可以通过编写模板来实现,其中假设模板类型具有某些接口。然后编译器在编译时实例化模板时强制执行。您可以使用SFINAE和/或static_asserts提供额外的强制执行,以确保使用的类型"是"或者更确切地说,符合代码使用的模板化界面。请注意,除了上述方法之外,没有像基本接口类那样直接定义此接口的方法。
请注意,静态多态性是您在编译时获得的。在运行时没有动态选择的类型。你需要某种形式的基类。