如何创建使用重写函数的非成员函数?
How can I make a non-member function which uses an overridden function?
在此代码中,我尝试重载 += 操作。在非成员部分中一切看起来都很好,但是当我编写一个非成员函数时,(这部分的+操作)它给出了无效的抽象返回类型错误,并说+=操作在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;
};
重写时使用 C++11override
上下文关键字。 这将使您的错误更接近您犯错误的地方。 也就是说,您没有覆盖。
你在别处被告知这一点,但这令人困惑。
这:
virtual AbstractBase &operator+=(const AbstractBase &other)=0;
具有与此不同的签名:
Vector1d &operator+=(const Vector1d &other);
第二个不会覆盖第一个。 它只是过载。 (他们是不同的!
此外,您还违反了LSP(见此处),这基本上表明您的设计存在根本错误。 我缺乏有关如何解决此问题的信息。 LSP 冲突不会导致生成中断。
要修复构建中断,只需执行以下操作:
Vector1d &operator+=(const AbstractBase &other) override; // and maybe final
(返回类型不完全匹配;这没关系,override
关键字会检查它,因为 C++ 中的协变返回类型规则。 协方差不适用于任何合理语言中的const&
参数(又名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;
}
现在,如果抽象类型与预期的类型不匹配,则会引发错误的强制转换。 这很可怕,但它会建立起来。
LSP 错误在于您的抽象基+=
意味着任何具有相同抽象基底的任何两个对象都可以+=
'd。 您的实现不同意,非常明智。 这意味着你的阶级等级制度是垃圾,应该被抛弃,可能不会被取代。 但这是一个更广泛的问题,比我在关于您的技术构建中断的 SO 答案中涵盖的问题要广泛。
从根本上说,您永远不会覆盖operator+=(const AbstractBase &other)
。
您提供了一个采用const Vector1d&
的新operator+=
,但这只允许将+=
与派生类型一起使用。
基类运算符+=
可以与任何AbstractBase
一起使用,因此当您重写它时,您需要保留签名,以便派生实现也适用于任何AbstractBase
。
这对于您的类层次结构可能没有意义,因此请仔细考虑抽象基类operator+=
的效用。
即使Vector1d
继承自AbstractBase
Vector1d &operator+=(const Vector1d &other);
没有与 相同的签名
AbstractBase &operator+=(const AbstractBase &other)=0
因此,它不能成为覆盖的候选项。
- 在 C++ 中用派生类型重写成员函数
- 重写虚拟函数和继承
- C++调用使用重写函数的父类函数
- 重写打印函数而不是覆盖基类
- 重写函数不打印基类数据
- 将一个小的 C 定义重写为"normal" C++函数
- 重写另一个方法 [C++] 使用的超类回调函数
- 具有派生参数的函数重写
- 在回调中使用函数时,C++未知重写说明符
- 用模板化函数重写虚拟函数
- 没有函数重写的多重继承.为什么模棱两可
- C++ 继承构造函数重写
- 关于C++中的虚拟函数重写
- C++函数重写不起作用
- 如何实现类变量的虚拟函数重写
- 将C++函数重写为C#(将指针传递到数组中的下一个元素)
- 引用可以用于实现函数重写吗
- 用函数重写嵌套的if-else语句
- C++继承函数重写
- 本机C++中的函数重写