使用带有虚函数的协变返回类型的 C++ 无效转换错误

标签 c++ c++11 virtual-functions covariant-return-types

在下面的代码中,我可以将 D::clone() 的返回值分配给指向 B 的指针,而不是指向 D 的指针。是否可以从基指针的调用中返回实际的多态类型?

struct B
{
    virtual B * clone() { return this; }
};

struct D : B
{
    D * clone()
    {
        std::cout << std::is_same<decltype(this), D *>::value << std::endl;
        return this;
    }
};

int main()
{
    B * b = new D();
    B * bb = b->clone(); // prints "1"
    std::cout << std::is_same<decltype(b->clone()), D *>::value << std::endl; // prints "0"
    D * d = b->clone(); // error: invalid conversion from B * to D * (GCC 5.1)
}

最佳答案

没有。调用clone()在底座上B A类D将返回D*转换到 B* .

您可以通过执行 static_cast<D*> 来扭转这种情况如果您绝对确定,或者 dynamic_cast<D*>如果你不确定。如果您确定,那么您应该真正将变量设置为 bD* .

在 C++ 中,无论运行时情况如何,您都应该在编译时将您所了解的程序状态编码为类型。通过存储D*进入B* b ,您告诉编译器“知道”所指向的数据“是 D ”。相反,您是说“使用 B*b 的代码应该对任何指向 B 的指针有效。显然 D* d = b->clone(); 不能保证对每个指向 B 的指针有效。

关于使用带有虚函数的协变返回类型的 C++ 无效转换错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31414735/

相关文章:

c++ - 虚继承和虚函数使用同一个虚表吗?

c++ - 调用重写虚方法的派生类调用父类方法调用了错误的方法

c++ - 如何处理可能是 std::string 或 std::wstring 的值

c++ - Linux 多线程 - 线程不会按预期产生任何输出

c++ - 检查内存是否归零的最快方法

c++ - 将 double 列表规范化为范围 -1 到 1 或 0 - 255

c++ - 在 move 构造函数之前调用析构函数?

c++ - constexpr 比 const 多 "constant"吗?

c++ - 为什么我不能在另一个文件中调用类的非默认构造函数?

c++ - 继承,覆盖和虚函数,以避免重复代码