代码之家  ›  专栏  ›  技术社区  ›  nbonneel

〔C++〕共变返回类型

  •  4
  • nbonneel  · 技术社区  · 14 年前

    我有一个 VectorN 班级,a Vector3 类继承自 向量

    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) {....};
    };
    

    此特定示例产生C2555错误:

    问题是我没有返回对 矢量3 矢量3 operator* . 但是,我想要我的 虚拟的,我想返回一个 矢量3 当我乘以 一个常数(否则,如果我 (Vector3*double).crossProduct(Vector3) ,它将返回一个错误)。

    我能做什么?

    谢谢!

    2 回复  |  直到 8 年前
        1
  •  6
  •   GManNickG    14 年前

    你需要重新设计。首先,更喜欢自由函数而不是成员函数。你应该拥有的唯一成员功能是那些需要进入私人空间的功能。

    从这个组合开始:

    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 .

    你得到的是 容易的 编写这些运算符的方法,因为您可以使用运算符的核心,并且由于协方差,返回类型匹配。


    vector valarray .

        2
  •  0
  •   Potatoswatter R. Martinho Fernandes    14 年前

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

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

    根本的问题是调用方需要为值返回的对象分配存储。这种存储不能动态变化,因此不可避免地要在堆上分配对象。