- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
Complex operator*(double m, const Complex & c) { return c * m; }
*在上面的代码中,我试图将一个常数乘以一个复数。我收到一些错误,其中之一是 [二进制“运算符 ”的参数太多]
ostream & operator<<(ostream & os, Complex & c) {os << c.real <<"," << c.imaginary; return os;}
*****你能告诉我我在这条线上做错了什么吗?谢谢*****
#include <iostream>
using namespace std;
class Complex
{
private:
double real;
double imaginary;
public:
Complex();
Complex(double r, double i = 0);
Complex operator*(const Complex & c) const;
Complex operator*(double mult) const;
Complex operator*(double m, const Complex & c)
{ return c * m; }
ostream & operator<<(ostream & os, Complex & c)
{os << c.real <<"," << c.imaginary; return os;}
};
Complex::Complex()
{
real = imaginary = 0;
}
Complex::Complex(double r, double i )
{
real = r;
imaginary = i;
}
Complex Complex::operator*(const Complex & c) const
{
Complex mult;
mult.imaginary = imaginary * c.imaginary;
mult.real = real * c.real;
return mult;
}
Complex Complex::operator*(double mult) const
{
Complex result;
result.real = real * mult;
result.imaginary = imaginary * mult;
return result;
}
int main()
{
Complex B(5, 40);
Complex C(6, 15);
cout << "B, and C:\n";
cout << B << ": " << C << endl;
cout << "B * C: " << B*C << endl;
cout << "10 * B: " << 10*B << endl;
return 0;
}
最佳答案
这两个操作符有问题:
class Complex {
// ...
Complex operator*(double m, const Complex & c)
{return c * m;}
ostream & operator<<(ostream & os, Complex & c)
{os << c.real <<"," << c.imaginary; return os;}
// ...
};
首先:operator<<
不应该改变复杂的输出,所以应该是 const
. (否则你不能输出临时对象,因为它们不能绑定(bind)到非常量引用。)
因为它们是非静态成员函数,所以它们有一个隐含的 this
范围。因此,它们具有三个参数。但是,两者都是二元运算符。由于您不能将它们设为静态(那只是因为规则如此规定),因此您必须将它们实现为自由函数。但是,在实现它们时,它们需要访问私有(private)成员,因此您必须让它们成为您类(class)的 friend :
class Complex {
// ...
friend Complex operator*(double m, const Complex & c);
friend ostream & operator<<(ostream & os, const Complex & c);
// ...
};
Complex operator*(double m, const Complex & c)
{return c * m;}
ostream & operator<<(ostream & os, const Complex & c)
{os << c.real <<"," << c.imaginary; return os;}
旁注,可以在友元声明处内联实现它们,这几乎可以让您回到原始版本:
// note the friend
class Complex {
// ...
friend Complex operator*(double m, const Complex & c)
{return c * m;}
friend ostream & operator<<(ostream & os, const Complex & c)
{os << c.real <<"," << c.imaginary; return os;}
// ...
};
但是,如果您实现具体的数学类型,则您的类型的用户会期望此类类型的所有通用操作都能与它一起使用。也就是说,例如,他们会期望 c*=r
简单地工作。所以你需要重载 operator*=
, 也。但该运算符几乎与 operator*
相同,因此在另一个之上实现一个是个好主意。一个常见的习惯用法是实现 *=
(和 +=
等)作为成员函数(因为它们改变了它们的左参数,对它们来说访问其私有(private)数据是个好主意)和 operator*
最重要的是作为非成员(member)。 (通常这比反过来更有效。):
// note the friend
class Complex {
// ...
Complex& operator*=(double rhs)
{return /* whatever */;}
friend ostream & operator<<(ostream & os, const Complex & c)
{os << c.real <<"," << c.imaginary; return os;}
// ...
};
inline Complex operator*(Complex lhs, double rhs) // note: lhs passed per copy
{return lhs*=rhs;}
inline Complex operator*(double lhs, const Complex& rhs)
{return rhs*lhs;}
IMO 这是最好的解决方案。
我有。但是,还有一些话要说:
您实现乘法的方式效率低下:
Complex Complex::operator*(const Complex & c) const
{
Complex mult;
mult.imaginary = imaginary * c.imaginary;
mult.real = real * c.real;
return mult;
}
当你说 Complex mult;
,您调用类的默认构造函数,它将实部和虚部初始化为 0
.接下来要做的是覆盖该值。为什么不一步完成:
Complex Complex::operator*(const Complex & c) const
{
Complex mult(real * c.real, imaginary * c.imaginary);
return mult;
}
甚至更简洁
Complex Complex::operator*(const Complex & c) const
{
return Complex(real * c.real, imaginary * c.imaginary);
}
当然,每次乘法只是两次赋值。但是然后 - 你不想在你的图形驱动程序的某些内部循环中使用它。
此外,您的构造函数未按照应有的方式 (TM) 实现。要初始化成员数据,您应该使用初始化列表:
Complex::Complex()
: real(), imaginary()
{
}
Complex::Complex(double r, double i)
: real(r), imaginary(i)
{
}
虽然对于 double
这样的内置类型没有任何区别,它也没有伤害,最好不要养成这个习惯。对于具有非平凡默认构造函数的用户定义类型(一个有点不幸的名称,因为它适用于所有非内置,甚至像 std::string
这样的类型,它不是由用户定义的),它确实使区别:它的效率要低得多。
原因是,当执行通过初始 {
时, C++ 保证你的数据成员对象是可访问和可用的。为此,必须构造它们,因为构造是将原始内存转换为对象的过程。因此,即使您没有显式调用构造函数,运行时系统仍会调用默认构造函数。如果接下来要做的是覆盖默认构造的值,那么您又在浪费 CPU 周期。
最后,这个构造函数Complex(double r, double i = 0)
用作隐式转换运算符。也就是说,例如,如果您打算调用 f(real)
, 但忘了包括它,但是有一个 f(const complex&)
在范围内,编译器行使它的权利来执行一个用户定义的转换和你的调用 f(4.2)
变成 f(Complex(4.2))
错误的函数被静默调用。那是非常危险的。
为了避免这种情况,您应该将所有构造函数标记为explicit
可以只用一个参数调用:
class Complex {
// ...
explicit Complex(double r, double i = 0)
// ...
};
关于c++ - 将一个常数乘以一个复数 & 运算符重载问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1751869/
Or 运算符 对两个表达式进行逻辑“或”运算。 result = expression1 Or expression2 参数 result 任意数值变量。 expression1 任意
Not 运算符 对表达式执行逻辑非运算。 result = Not expression 参数 result 任意数值变量。 expression 任意表达式。 说明 下表显示如何
Is 运算符 比较两个对象引用变量。 result = object1 Is object2 参数 result 任意数值变量。 object1 任意对象名。 object2 任意
\ 运算符 两个数相除并返回以整数形式表示的结果。 result = number1\number2 参数 result 任意数值变量。 number1 任意数值表达式。 numbe
And 运算符 对两个表达式进行逻辑“与”运算。 result = expression1 And expression2 参数 result 任意数值变量。 expression1
运算符(+) 计算两个数之和。 result = expression1 + expression2 参数 result 任意数值变量。 expression1 任意表达式。 exp
我对此感到困惑snippet : var n1 = 5-"4"; var n2 = 5+"4"; alert(n1); alert(n2); 我知道 n1 是 1。那是因为减号运算符会将字符串“4”转
我想我会得到 12,而不是 7。 w++,那么w就是4,也就是100,而w++, w 将是 8,1000;所以 w++|z++ 将是 100|1000 = 1100 将是 12。 我怎么了? int
Xor 运算符 对两个表达式进行逻辑“异或”运算。 result = expression1 Xor expression2 参数 result 任意数值变量。 expression1
Mod 运算符 两个数值相除并返回其余数。 result = number1 Mod number2 参数 result 任意数值变量。 number1 任意数值表达式。 numbe
Imp 运算符 对两个表达式进行逻辑蕴涵运算。 result = expression1 Imp expression2 参数 result 任意数值变量。 expression1 任
Eqv 运算符 执行两个表达式的逻辑等价运算。 result = expression1 Eqv expression2 参数 result 任意数值变量。 expression1 任
我有一个运算符重载的简单数学 vector 类。我想为我的运算符(operator)获取一些计时结果。我可以通过计时以下代码轻松计时我的 +=、-=、*= 和/=: Vector sum; for(s
我是用户定义比较运算符的新手。我正在读一本书,其中提到了以下示例: struct P { int x, y; bool operator、运算符<等),我们
在 SQL 的维基百科页面上,有一些关于 SQL 中 bool 逻辑的真值表。 [1] 维基百科页面似乎来源于 SQL:2003 标准。 等号运算符 (=) 的真值表与 SQL:2003 草案中的 I
我遇到了一个奇怪的 C++ 运算符。 http://www.terralib.org/html/v410/classoracle_1_1occi_1_1_number.html#a0f2780081f
我正在阅读关于 SO 和 answers 中的一个问题,它被提到为: If no unambiguous matching deallocation function can be found, pr
我偶然发现了这个解决方案,但我无法理解其中到底发生了什么。谁能解释一下! 据我了解,它试图通过计算一半的单元格然后将其加倍来计算 a*b 网格中的单元格数量。但是我无法理解递归调用。 请不要建议其他解
Go的基本类型 布尔类型bool 长度:1字节 取值:布尔类型的取值只能是true或者false,不能用数字来表示 整型 通用整型 int / uint(有符号 / 无符号,下面也类似) 长度:根据运
在本教程中,您将学习JavaScript中可用的不同运算符,以及在示例的帮助下如何使用它们。 什么是运算符? 在JavaScript中,运算符是一种特殊符号,用于对运算数(值和变量)执行操作。例如,
我是一名优秀的程序员,十分优秀!