简体   繁体   English

[C ++]协变返回类型

[英][C++]Covariant return types

I have a VectorN class, and a Vector3 class inherited from VectorN (which can handle cross products for example). 我有一个VectorN类,一个从VectorN继承的Vector3类(例如可以处理交叉产品)。 I have trouble determining the return types of the different operators. 我无法确定不同运营商的返回类型。 Example: 例:

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

This particular example produces a C2555 error: 此特定示例产生C2555错误:

'Vector3::operator *': overriding virtual function return type differs and is not covariant from 'VectorN::operator *', see declaration of 'VectorN::operator *'. 'vector3 :: operator *':覆盖虚函数返回类型不同,并且不是'VectorN :: operator *'的协变,请参见'VectorN :: operator *'的声明。

The problem is that I don't return a reference to a Vector3 , and that the Vector3 class is not fully defined at the declaration of the operator* . 问题是我没有返回对Vector3的引用,并且在operator*的声明中没有完全定义Vector3类。 However, I want my operator* to be virtual, and I want to return a Vector3 when I multiply a Vector3 with a constant (otherwise, if I do (Vector3*double).crossProduct(Vector3) , it would return an error). 但是,我希望我的operator*是虚拟的,并且当我将Vector3与常量相乘时我想返回Vector3 (否则,如果我这样做(Vector3*double).crossProduct(Vector3) ,它将返回错误)。

What can I do ? 我能做什么 ?

Thanks! 谢谢!

You need a re-design. 你需要重新设计。 First, prefer free-functions over member-functions. 首先,更喜欢免费功能而不是成员功能。 The only member functions you should have are the ones that need access to privates. 您应该拥有的唯一成员函数是需要访问私有函数的成员函数。

Start with this combo: 从这个组合开始:

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

Here covariance works fine because the type is a reference or pointer, and you re-use code. 协方差在这里工作得很好,因为类型是引用或指针,并且您可以重用代码。 ( static_cast is free, performance-wise, and safe since you know the derived type.) static_cast是免费的,性能方面的,并且是安全的,因为您知道派生类型。)

Then you implement your free-functions: 然后你实现你的自由功能:

// 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;
}

Do the same with Vector3 . Vector3做同样的事情。

What's been done is you get an easy way to write these operators because you get to use the core of the operator, and the return type matches, thanks to covariance. 所做的是你有一个简单的方法来编写这些运算符,因为你可以使用运算符的核心,并且由于协方差,返回类型匹配。


Do heed warnings though, you probably don't need any of it. 不过要注意警告,你可能不需要任何警告。 And extensions you want to make can be made via free-functions operating on a vector or valarray . 您想要制作的扩展可以通过在vectorvalarray上运行的自由函数来valarray

The best I can think of is to replace the return type with a smart pointer and forgo covariance in favor of polymorphism: 我能想到的最好的方法是用智能指针替换返回类型,放弃协方差,支持多态:

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

The reason I suggest this is that you are using virtual functions, so knowing the exact type of the object isn't necessary anyway. 我建议这样做的原因是你正在使用虚函数,所以无论如何都不需要知道对象的确切类型。

The underlying problem is that the caller needs to allocate storage for an object returned by value. 根本问题是调用者需要为value返回的对象分配存储空间。 That storage cannot vary dynamically, so you are inevitably stuck allocating the object on the heap. 该存储不能动态变化,因此您不可避免地无法在堆上分配对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM