【发布时间】:2021-01-19 15:37:52
【问题描述】:
这是Static polymorphism with final or templates? 的后续问题。因此,仅静态多态性的最佳解决方案似乎是使用 CRTP。如果你想要运行时多态,虚函数是一个很好的解决方案。
我发现这不是很优雅,因为问题实际上非常相似(也许您想在某个时候更改行为)但代码实际上非常不同。如果解决方案非常相似并且仅在一个地方有所不同,那么我认为代码将更具表现力。
所以我想知道是否有一种方法可以通过虚函数获得仅静态的多态性。这可能类似于属性或某些结构,不允许指向抽象基类的指针。是否有这样的功能,如果没有,我是否遗漏了为什么不应该存在这样的功能?静态多态性和运行时多态性实际上是否比这样的特性所暗示的更加不同?
编辑:为了让问题和用例更清楚,这里有一些我想写的例子:
[[abstract]] class Base {
public:
void bar() { /* do something using foo() */ }
private:
virtual void foo() = 0;
};
class Derived1 : public Base {
public:
Derived1();
private:
void foo() override { /* do something */};
};
class Derived2 : pulic Base {
public:
Derived2();
private:
void foo() override { /* do something with data */ }
int data;
};
其中不存在的属性 [[abstract]] 意味着不存在 Bass 类的实例,即使不存在指针也是如此。这将清楚地表达静态多态性,并且编译器可以优化掉虚拟调用,因为它们不存在。也不需要虚拟析构函数。
编辑 2:目标是提供一个抽象接口,该接口可以在进一步的派生类中稍作修改,并且具有与抽象类相同的扩展选项。所以主要实现还是在Base,虚函数的具体实现在Derived。
【问题讨论】:
-
由于虚函数仅用于运行时多态性,我不确定您尝试“使用虚函数获得仅静态多态性”是什么意思。这就像在干水中游泳一样,因为您不想被淋湿。
-
什么代码有很大不同?对象上的静态或动态调度方法调用的位置?您绝对可以编写一个函数模板,根据类型参数生成虚拟和非虚拟调用。那是你想做的吗?这个问题很不清楚。
-
我想要仅静态的多态,代码方面看起来与运行时多态的虚函数非常相似,例如,它可以很容易地交换以支持运行时多态。例如,我不喜欢 CRTP 包含大量样板,只是为了表达您想要静态多态而不是运行时多态。
-
@Henk 一个实际的用例会让你的问题更清楚。仅将其称为“静态多态性”在不同的上下文中可能意味着不同的东西。可以说,单独的 CRTP 不提供任何类型的多态性,因为没有通用的基础或接口契约,而是类似于将代码注入到任意数量的不同类中。
-
对了,是不是你想要看起来相似的多态类型的声明和定义?还是使用它们的代码?
标签: c++ polymorphism