C++ [C+;+;]协变返回类型
我有一个C++ [C+;+;]协变返回类型,c++,virtual,C++,Virtual,我有一个vector类,还有一个继承自vector的Vector3类(例如,它可以处理交叉乘积)。我很难确定不同运算符的返回类型。例如: class VectorN { public: VectorN(){}; virtual VectorN operator*(const double& d) {.....}; std::vector<double> coords; }; class Vector3 : public VectorN { public:
vector
类,还有一个继承自vector
的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) {....};
};
类向量机
{
公众:
向量();
虚拟向量撕裂算子*(constdouble&d){……};
std::向量坐标;
};
类向量3:公共向量
{
公众:
向量3(){};
虚向量3算子*(常数双d){……};
};
此特定示例产生C2555错误:
“Vector3::operator*”:重写虚拟函数返回类型与“Vector3::operator*”不同且不协变,请参阅“Vector3::operator*”的声明
问题是我没有返回对Vector3
的引用,并且Vector3
类在操作符*
的声明中没有完全定义。但是,我希望我的操作符*
是虚拟的,当我将向量3
与常数相乘时,我希望返回一个向量3
(否则,如果我使用(向量3*double)。叉积(向量3)
,它将返回一个错误)
我能做什么
谢谢 我能想到的最好办法是用智能指针替换返回类型,放弃协方差而支持多态性:
virtual auto_ptr< VectorN > operator*(const double& d);
virtualauto_ptroperator*(const double&d);
我建议这样做的原因是,您使用的是虚拟函数,因此不需要知道对象的确切类型
潜在的问题是调用方需要为值返回的对象分配存储。该存储不能动态变化,因此您不可避免地要在堆上分配对象。您需要重新设计。首先,与成员函数相比,更喜欢自由函数。你应该拥有的唯一成员功能是那些需要访问私人空间的功能 从这个组合开始:
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));
};
};
对向量3执行相同的操作
我们所做的是得到一种编写这些运算符的简单方法,因为您可以使用运算符的核心,并且由于协方差,返回类型匹配
不过,请注意警告,您可能不需要任何警告。你想做的扩展可以通过在
向量
或数组
上操作的自由函数来实现。好吧,用指针替换对象的方法是auto_ptr
/unique_ptr
,但它们不能是协变的!顺便说一下,不要通过常量传递原语&
,而是通过值传递原语。(不要通过const&
或任何小于sizeof(void*)
的原语传递任何原语)既然我已经回答了这个问题,为什么你不使用现成的数字库呢?这个功能甚至在标准asvalarray
@user中也有:这些东西应该是免费函数。总是喜欢自由函数。@用户:这种功能是建立在库之上的,比如valarray
(或者几十种自由的替代品中的任何一种)。重新实现向量和点积会让你走上一条错误的道路,很难扭转局面。而且,生成随机向量或转换颜色空间应该是自由函数(类外),而不是方法。类不是库。我不熟悉auto_ptr,但我会看看这个。。。谢谢!:)或者…只需使用valarray
。同时拥有vectorred
和vector3
意味着他想要一个模板过大的代数向量库。你知道一个简单的吗?+1:很好!但是有一件事,当你说“Makev
overconst-vector
允许Vector3
使用它…”时,你错过了一个符号吗?大概这个参数需要是一个引用,以避免在*=
?@Troubador上进行切片和丢失虚拟调度。不,他建议按值传递和返回,并复制所有函数。这真的是模板的问题。@Troubadour:是的,但再看一眼就没意义了。谢谢你们的回答!我想我会选择这个解决方案,至少对运营商来说是这样
// 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;
}