重载C++算术运算符
Overloading C++ arithmetic operators
我正在尝试创建一些重载算术运算符,它们使用继承的类,如
class Block {
public:
Block() {}
virtual double Value() {};
};
class Constant : public Block {
public:
Constant(double v) { value = v; }
virtual double Value() { return value; }
private:
double value;
};
class Add : public Block {
public:
Add(Block &a, Block &b) { value1 = &a; value2 = &b; }
virtual double Value() { return value1->Value() + value2->Value(); }
private:
Block *value1;
Block *value2;
};
Block operator + (Block &a, Block &b) {
return new Add(a, b);
}
int main() {
Constant a(5.0);
Constant b(6.0);
printf("%.3f", (a+b).Value());
}
但我得到了以下内容:error: conversion from 'Add*' to non-scalar type 'Block' requested
这是我第一次在C++中使用OOP,所以我的想法可能吗?
一般来说,运算符重载和继承不会协同工作很好,因为在C++中,运算符通常具有值语义。然而,有一个主要的例外,如果所有Add
类的实例实际上是返回值你的operator+
(临时),那么你已经有效地实现的编译时表达式评估—非常重要的优化技术。(在现代C++中,这是通常使用模板而不是继承来完成,但是原理是一样的。)
因为运算符具有值语义,所以它们应该返回值,而不是指针。这意味着没有new
。另一个原因不是使用new
是指任何new
ed都必须显式已删除,在大多数情况下,无法显式删除作为表达式的一部分返回的指针。还有这样一个指针也必须取消引用。
编辑:
我似乎忘记了一个重要的点:运算符的声明返回值必须是您返回的实际类型,因为您的返回表达式将被复制到该类型中。因此:
Add
operator+( Block const& lhs, Block const& rhs )
{
return Add( lhs, rhs );
}
还要注意const
。没有它,就无法使用运算符关于临时措施;例如a + b + c
将是非法的(假设a
、b
和c
属于Block
类型,或者属于某种派生类型从中)。
由于您没有提到导致错误的代码的特定部分,让我指出:
Block operator + (Block &a, Block &b) {
return new Add(a, b);
}
这里到底发生了什么?好吧,您承诺返回Block
,但实际上返回的是new Add(a, b)
,即Add*
。这就是编译器所抱怨的。
这是我第一次在C++中使用OOP
我们可以从所有的指针、新闻和虚拟信息中分辨出来。您的代码存在严重的生存期问题。
我强烈建议你忘记你的C++OOP知识,读一本关于C++的入门书。
- 为什么比较运算符如此快速
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 增量运算符与后缀混淆
- 一个关于在C++中重载布尔运算符的问题
- 运算符C++ "delete []"仅删除 2 个前值
- 模板类无法识别友元运算符
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 关闭||运算符优化
- 通过继承类使用来自不同命名空间的运算符
- C++Cast运算符过载
- 如何使用AngelScript注册SFML Vector2运算符
- 重载元组索引运算符-C++
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 布尔比较运算符是如何在C++中工作的
- 重载运算符new[]的行为取决于析构函数
- 如何防止clang格式在流运算符调用之间添加换行符<<