在这段代码中我尝试基本上重载+ =操作.在非成员部分看起来一切都很好,但是当我写一个非成员函数时,(+这部分中的操作)它给出了无效的抽象返回类型错误,并说+ = operation在vector1d中是纯粹的.我怎么解决这个问题?
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;
};
Run Code Online (Sandbox Code Playgroud)
override覆盖时使用C++ 11 上下文关键字.这会使你的错误更接近你犯错的地方.这是你没有覆盖的.
你在其他地方被告知这一点,但令人困惑.
这个:
virtual AbstractBase &operator+=(const AbstractBase &other)=0;
Run Code Online (Sandbox Code Playgroud)
签名与此不同:
Vector1d &operator+=(const Vector1d &other);
Run Code Online (Sandbox Code Playgroud)
第二个不会覆盖第一个.它只是超载.(它们是不同的!)
您还违反了LSP(参见此处),这基本上表明您的设计存在根本性错误.我缺乏有关如何解决该问题的信息.LSP违规不会导致生成中断.
要修复构建中断,只需执行以下操作:
Vector1d &operator+=(const AbstractBase &other) override; // and maybe final
Run Code Online (Sandbox Code Playgroud)
(返回类型不完全匹配;这是好的,并且override关键字检查它,因为C++中的协变返回类型规则.协方差不适用于const&任何合理语言中的参数(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;
}
Run Code Online (Sandbox Code Playgroud)
如果抽象类型与您期望的类型不匹配,现在会抛出一个错误的强制转换.哪个很糟糕,但它会建立起来.
LSP错误是你的抽象基础+=意味着具有相同抽象基数的任何两个对象都可以是+='d.你的实施并不一致,非常合理.这意味着你的班级heirarchy是垃圾,应该被扔掉,可能不会被替换.但这是一个比我在技术构建中断的SO答案中所涵盖的更广泛的问题.