在这段代码中我尝试基本上重载+ =操作。在非成员部分中一切看起来都没问题,但是当我写一个非成员函数时,(+部分中的操作)它给出了无效的抽象返回类型错误并且说 + =操作是纯粹的vector1d 即可。我该如何解决这个问题?
import React, { PropTypes } from 'react'
import map from "lodash/map"
import $ from 'jquery';
import "../../app/assets/vendors/select2/dist/js/select2.full.min.js"
class SingleSelect extends React.Component{
componentDidMount() {
$(this.refs.singleselect).select2({
placeholder: this.props.placeholder
});
}
changed(){console.log("Changed")}
render () {
const taged_options = map(this.props.options, (val, key) =>
<option key={ key } value={val}>{val} </option>
)
return (
<div className="form-group">
<label className="control-label col-md-3 col-sm-3 col-xs-12">
{this.props.label}
</label>
<div className="col-md-8 col-sm-6 col-xs-12">
<select
onChange={this.changed}
ref="singleselect"
className="form-control"
value="Wholesaler"
name={this.props.name}
>
{taged_options}
</select>
</div>
</div>
)
}
}
SingleSelect.propTypes = {
label: React.PropTypes.string.isRequired,
placeholder: React.PropTypes.string.isRequired,
required: React.PropTypes.bool.isRequired,
options: React.PropTypes.object.isRequired,
}
SingleSelect.defaultProps = {
placeholder: "Select a value from list"
};
export default SingleSelect
答案 0 :(得分:5)
覆盖时使用C ++ 11 override
上下文关键字。这会使你的错误更接近你犯错的地方。这是你没有覆盖的。
你在其他地方被告知,但这很令人困惑。
此:
virtual AbstractBase &operator+=(const AbstractBase &other)=0;
与此签名不同:
Vector1d &operator+=(const Vector1d &other);
第二个不会覆盖第一个。它只是超载。 (他们是不同的!)
您还违反了LSP(see here),这基本上表明您的设计存在根本性错误。我缺乏有关如何解决该问题的信息。 LSP违规不会导致构建中断。
要修复构建中断,只需执行以下操作:
Vector1d &operator+=(const AbstractBase &other) override; // and maybe final
(返回类型不完全匹配;这是正常的,override
关键字检查它,因为C ++中的协变返回类型规则。协方差不适用于const&
参数(也就是说)在任何明智的语言中(逆向可能是明智的,但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;
}
如果抽象类型与您期望的类型不匹配,则现在抛出错误的强制转换。这是可怕的,但它建立。
LSP错误是您的抽象基础+=
暗示具有相同抽象基数的任何两个对象可以是+=
'd。你的实施并不一致,非常合理。这意味着你的班级heirarchy是垃圾,应该被扔掉,可能不会被替换。但这是一个比我在技术构建中断的答案中所能涵盖的更广泛的问题。
答案 1 :(得分:4)
从根本上说,你永远不会覆盖operator+=(const AbstractBase &other)
。
您提供的新operator+=
需要const Vector1d&
,但这只允许+=
使用派生类型。
基类操作符+=
可以与任何AbstractBase
一起使用,因此当您覆盖它时,您需要保留签名,以便派生的实现也适用于任何AbstractBase
。 / p>
这可能对你的班级层次没有意义,所以要仔细考虑抽象基类的效用&#39; operator+=
。
答案 2 :(得分:3)
即使Vector1d
继承自AbstractBase
Vector1d &operator+=(const Vector1d &other);
与
的签名不同 AbstractBase &operator+=(const AbstractBase &other)=0
因此,它不能成为覆盖的候选者。