[C ++]协变返回类型

时间:2010-08-18 21:33:00

标签: c++ virtual

我有一个VectorN类,以及一个继承自Vector3的{​​{1}}类(可以处理交叉产品)。我无法确定不同运营商的返回类型。例如:

VectorN

此特定示例产生C2555错误:

  

'Vector3 :: operator *':覆盖虚函数返回类型不同,并且不是'VectorN :: operator *'的协变,请参阅'VectorN :: operator *'的声明。

问题是我没有返回对class VectorN { public: VectorN(){}; virtual VectorN operator*(const double& d) {.....}; std::vector<double> coords; }; class Vector3 : public VectorN { public: Vector3(){}; virtual Vector3 operator*(const double& d) {....}; }; 的引用,并且Vector3类未在Vector3的声明中完全定义。但是,我希望我的operator*是虚拟的,我希望在operator*乘以常量时返回Vector3(否则,如果我Vector3,则会返回错误。)

我该怎么办?

谢谢!

2 个答案:

答案 0 :(得分:6)

您需要重新设计。首先,更喜欢免费功能而不是成员功能。您应该拥有的唯一成员函数是需要访问私有函数的成员函数。

从这个组合开始:

class VectorN
{
public:
   virtual VectorN& operator*=(double d)
    {
        /* ... */

        return *this;
    };
};


class Vector3 : public VectorN
{
public:
    virtual Vector3& operator*=(double d)
    {
        return static_cast<Vector3&>(VectorN::operator*=(d));
    };
};

这里协方差工作正常,因为类型是引用或指针,并且您重用代码。 (static_cast是免费的,性能明智且安全的,因为您知道派生类型。)

然后你实现你的自由功能:

// optimization: if you're going to make a copy, do it in the parameter list;
// compilers can elide a copy when working with temporaries
VectorN operator*(VectorN v, double d)
{
    // reuse code
    return v *= d;
}

VectorN operator*(double d, VectorN v)
{
    // reuse code
    return v *= d;
}

Vector3执行相同操作。

通过协方差,您可以使用 easy 方式编写这些运算符,因为您可以使用运算符的核心,并且返回类型匹配。


但是,请注意警告,你可能不需要任何警告。您想要制作的扩展程序可以通过vectorvalarray上运行的免费功能制作。

答案 1 :(得分:0)

我能想到的最好的方法是用智能指针替换返回类型,放弃协方差,支持多态:

virtual auto_ptr< VectorN > operator*(const double& d);

我建议这样做的原因是你正在使用虚函数,所以无论如何都不需要知道对象的确切类型。

根本问题是调用者需要为value返回的对象分配存储空间。该存储不能动态变化,因此您不可避免地无法在堆上分配对象。