【问题标题】:C++ covariant returning type applicationC++协变返回类型应用程序
【发布时间】:2015-04-20 09:54:27
【问题描述】:

我想询问协变返回类型和可能(非)应用程序。我以为我发现了一些新的设计模式,但遗憾的是它不起作用:(

让我们从一个例子开始:

// test.h 
class B {public: virtual B* getSelf() {return this;} };
class D : public B { public: D* getSelf() {return static_cast<D*>(this);} };

void compute(B* something); 
void compute(D* something);

// test.cpp 
int main() 
{
B* b = new D(); 
compute(b->getSelf()); // This calls compute(B*), not compute(D*) 
}

知道为什么它不起作用吗?

PS 我为糟糕的格式道歉

编辑:当然,如果我在 main 中使用强制转换,它会正确调用 compute(D*)。

编辑 #2:我尽量避免切换 :)

【问题讨论】:

    标签: c++ design-patterns covariance covariant


    【解决方案1】:

    函数重载解析在编译时完成,取决于表达式的静态类型而不是动态类型。

    b-&gt;getSelf() 的类型是 B*,因为这是在 B 类型的实例上调用成员函数 getSelf 的返回类型。 此时b 在运行时将指向BCD 并不重要,您存储在该指针中的任何子实例都不会影响其静态类型。

    也就是说,您尝试实现的目标似乎可以通过简单的多态性(使 compute 成为成员函数)来解决,或者如果您不希望这样做,您可以使用 double dispatching

    【讨论】:

    • 感谢您的回复。和我想象的一样。简单的多态性不适用于我的具体情况,因为我想将计算部分与对象分开。 C++ 中的双重调度已在 Alexandrescu 现代 C++ 设计一书中进行了处理,所以我想我应该再研究一下。
    • 我的目标是将对象与计算部分(如 STL)分离,没有编译时间限制(即它应该在运行时工作)。
    • @user3770392 如果您想要对象和计算之间真正通用的分离,您将需要对象之间更强大的通用“接口”(可能是一个概念,而不是一个真正的类)。 STL 实现了这一点,这要归功于几乎所有容器都实现的模板和迭代器的概念。通过为每个对象编写一个重载来将计算与对象分离(而不是使其成为成员函数)并不会带来太多通用性或易于维护,它只会为您带来更多 cpp 文件:)
    • 是的,这是有道理的。我唯一怀疑的是可扩展性。例如,使用普通的多态方法,每次我想添加计算能力时,我都必须添加一个函数成员,这使得我的类太大而臃肿:(
    猜你喜欢
    • 2017-02-28
    • 2011-09-02
    • 2021-03-21
    • 1970-01-01
    • 2021-02-24
    • 1970-01-01
    • 1970-01-01
    • 2020-06-14
    • 1970-01-01
    相关资源
    最近更新 更多