C++ 如何生成使用重写函数的非成员函数?
在这段代码中,我尝试重载+=操作。在非成员部分中,一切看起来都正常,但当我编写一个非成员函数时,(+操作在此部分),它给出了无效的抽象返回类型错误,并表示+=操作在vector1d中是纯的。我怎样才能解决这个问题C++ 如何生成使用重写函数的非成员函数?,c++,oop,operators,C++,Oop,Operators,在这段代码中,我尝试重载+=操作。在非成员部分中,一切看起来都正常,但当我编写一个非成员函数时,(+操作在此部分),它给出了无效的抽象返回类型错误,并表示+=操作在vector1d中是纯的。我怎样才能解决这个问题 class AbstractBase{ public: virtual AbstractBase &operator+=(const AbstractBase &other)=0; private: }
class AbstractBase{
public:
virtual AbstractBase &operator+=(const AbstractBase &other)=0;
private:
}
////
class Vector1d:public AbstractBase{
public:
Vector1d &operator+=(const Vector1d &other);
private:
int size_;
vector<double> data_;
}
//non member func
Vector1d operator+(const Vector1d& vec1, const Vector1d& vec2);
///
Vector1d &Vector1d::operator+=(const Vector1d &other){
cout<<"sum operator is called"<<endl;
for(int i = 0; i < other.size_ ; i++)
data_.at(i) += other.data_.at(i);
return *this;
}
Vector1d operator+(const Vector1d& vec1, const Vector1d& vec2){
return (Vector1d) vec1 += vec2;
};
类抽象库{
公众:
虚拟抽象库和运算符+=(常量抽象库和其他)=0;
私人:
}
////
类Vector1d:公共抽象库{
公众:
向量1d和运算符+=(常量向量1d和其他);
私人:
int-size_389;;
矢量数据;
}
//非成员函数
Vector1d运算符+(常量Vector1d和vec1,常量Vector1d和vec2);
///
Vector1d和Vector1d::运算符+=(常量Vector1d和其他){
即使Vector1d
继承自AbstractBase
Vector1d&operator+=(常量Vector1d&other);
没有与相同的签名
AbstractBase和operator+=(const AbstractBase和other)=0
因此,它不能作为覆盖的候选对象。即使Vector1d
继承自AbstractBase
Vector1d&operator+=(常量Vector1d&other);
没有与相同的签名
AbstractBase和operator+=(const AbstractBase和other)=0
因此,它不能作为覆盖的候选对象。基本上,您永远不会覆盖运算符+=(const AbstractBase&other)
您提供了一个新的运算符+=
,它接受常量向量1d&
,但这只允许对派生类型使用+=
基类运算符+=
可以与任何AbstractBase
一起使用,因此当您重写它时,需要保留签名,以便派生实现也可以与任何AbstractBase
一起使用
这对于您的类层次结构可能没有意义,因此请仔细考虑抽象基类“操作符+=
”的实用性。从根本上说,您永远不会覆盖操作符+=(const AbstractBase&other)
您提供了一个新的运算符+=
,它接受常量向量1d&
,但这只允许对派生类型使用+=
基类运算符+=
可以与任何AbstractBase
一起使用,因此当您重写它时,需要保留签名,以便派生实现也可以与任何AbstractBase
一起使用
这可能对您的类层次结构没有意义,因此请仔细考虑抽象基类“运算符+=
的实用程序,在重写时使用C++11override
上下文关键字。这将使您的错误更接近您犯错误的地方。也就是说,您没有重写
其他地方也有人告诉你这一点,但这令人困惑
这:
具有与此不同的签名:
Vector1d &operator+=(const Vector1d &other);
第二个并没有覆盖第一个。它只是重载。(它们是不同的!)
您违反了LSP addition(),它基本上说明您的设计存在基本错误。我缺少有关如何解决该问题的信息。违反LSP不会导致构建中断
要修复构建中断,只需执行以下操作:
Vector1d &operator+=(const AbstractBase &other) override; // and maybe final
(返回类型不匹配),这是可以的,并且<代码>重写< /Cord>关键字检查它,因为C++中的协变返回类型规则。Covariance不适用于任何代码中的<代码> const和< /c> >参数(AKA,in)。(逆变可以明智,但C++不提供免费的,无论如何,你也不想去做。)
至于身体:
Vector1d &Vector1d::operator+=(const AbstractBase &other_abstract){
auto& other = dynamic_cast<Vector1d const&>(other_abstract); // can throw
std::cout<<"sum operator is called"<<std::endl;
for(int i = 0; i < other.size_ ; i++)
data_.at(i) += other.data_.at(i);
return *this;
}
Vector1d&Vector1d::operator+=(const AbstractBase&other_abstract){
auto&other=dynamic_cast(other_abstract);//可以抛出
std::cout在重写时使用C++11override
上下文关键字。这将使您的错误更接近您犯错误的地方。也就是说,您没有重写
其他地方也有人告诉你这一点,但这令人困惑
这:
具有与此不同的签名:
Vector1d &operator+=(const Vector1d &other);
第二个并没有覆盖第一个。它只是重载。(它们是不同的!)
您违反了LSP addition(),它基本上说明您的设计存在基本错误。我缺少有关如何解决该问题的信息。违反LSP不会导致构建中断
要修复构建中断,只需执行以下操作:
Vector1d &operator+=(const AbstractBase &other) override; // and maybe final
(返回类型不匹配),这是可以的,并且<代码>重写< /Cord>关键字检查它,因为C++中的协变返回类型规则。Covariance不适用于任何代码中的<代码> const和< /c> >参数(AKA,in)。(逆变可以明智,但C++不提供免费的,无论如何,你也不想去做。)
至于身体:
Vector1d &Vector1d::operator+=(const AbstractBase &other_abstract){
auto& other = dynamic_cast<Vector1d const&>(other_abstract); // can throw
std::cout<<"sum operator is called"<<std::endl;
for(int i = 0; i < other.size_ ; i++)
data_.at(i) += other.data_.at(i);
return *this;
}
Vector1d&Vector1d::operator+=(const AbstractBase&other_abstract){
auto&other=dynamic_cast(other_abstract);//可以抛出
std::运算符不能是纯虚拟的吗?问题是运算符+=(AbstratctBase)和运算符+=(Vector1d)具有不同的签名,因此后者不会覆盖第一个。只有虚拟函数的返回类型是协变的,而不是参数类型。代码中还有许多其他错误(例如,类声明后缺少;
,是否为向量标准::向量?-如果是,则无#包括和使用语句无)。请务必粘贴收到确切错误消息时使用的示例。@StoryTeller同意,但对*
的定位说同样的话,人们称你为心理缺陷运算符不能是纯虚拟的吗?问题是运算符+=(Abstractbase)和运算符+=(Vector1d)有不同的签名,所以后者