- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
#include<iostream>
using namespace std;
class complex {
double real;
double image;
public:
complex(double r=0,double i=0) : real(r), image(i) { };
complex(const complex& c) : real(c.real), image(c.image) { };
~complex(){};
double re() const {
return real;
};
double im() const{
return image;
};
const complex& operator =(const complex&c)
{
real = c.real;
image = c.image;
return *this;
};
const complex& operator +=(const complex&c)
{
real += c.real;
image += c.image;
return *this;
};
const complex& operator -=(const complex&c)
{
real -= c.real;
image -= c.image;
return *this;
};
const complex& operator *=(const complex&c)
{
double keepreal=real;
real = real * c.real - image * c.image;
image = keepreal * c.image + image * c.real;
return *this;
};
const complex& operator /=(double d)
{
real/=d;
image/=d;
return *this;
};
friend complex operator !(const complex &c)
{
return complex(c.re(),-c.im());
};
friend double abs2(const complex& c)
{
return (c.re() * c.re() + c.im() * c.im());
};
const complex& operator /=(const complex&c)
{
return *this *= (!c) /= abs2(c);
};
const complex operator +(const complex& c, const complex& d)
{
return complex(c.re() + d.re(), c.im() + d.im());
};
const complex operator -(const complex& c, const complex& d)
{
return complex(c.re() - d.re(), c.im() - d.im());
};
const complex operator -(const complex&c)
{
return complex(-c.re(), -c.im());
};
const complex operator /(const complex& c,const complex& d)
{
return complex(c) /= d;
};
};
int main() {
complex c = 1., d(3.,4.);
return 0;
}
输出:
Line 62: error: 'const complex complex::operator+(const complex&, const complex&)' must take either zero or one argument
compilation terminated due to -Wfatal-errors.
最佳答案
有两种方法可以重载二元 + 运算符,作为自由函数或作为成员函数。作为成员函数,签名是 Type operator+( Type const & ) const
(const
在那里是可选的,但我假设 a+b
不修改 a
,这似乎是一个合理的假设)。
另一种方法是使用一个自由函数,它接受两个对象并返回总和。对此有不同的签名,但最广泛接受的是:Type operator+(Type lhs, Type const & rhs)
(注意第一个参数是按值) ,其中实现在内部修改并返回 lhs
。特别是算术运算符重载的一种常见方法是将 operator+=
实现为成员函数,然后根据前者实现一个自由函数 operator+
:
struct Type {
// ...
Type& operator+=( Type const & );
};
Type operator+( Type lhs, Type const & rhs ) {
return lhs+=rhs;
}
这样,您就不需要将友元授予 free 函数。在某些情况下,特别是模板,有时建议在类定义中定义运算符,在这种情况下,您必须将其设为 friend
(不是为了访问,而是出于句法原因:
struct Type {
// ...
Type& operator+=( Type const & );
// Still a free function:
friend Type operator+( Type lhs, Type const & rhs ) {
return lhs+=rhs;
}
};
至于使用这种模式的原因...首先实现 operator+=
然后在其之上实现 operator+
提供了两个独立的操作,而额外的成本很小(operator+
是一个单行函数!)。将其实现为成员函数(operator+=
也可以是自由函数)使其类似于 operator=
(必须是成员)并且避免了友元的需要。
将operator+
实现为自由函数的原因与操作的类型对称性有关。加法是可交换的 (a+b
== b+a
),您在使用您的类型时会期望相同。您提供了一个隐式构造函数(由于构造函数 complex( double r = 0, double i = 0 )
,您的复杂类型可以从 int 隐式转换,并且允许编译器使用这些转换如果函数调用不完全匹配重载。
如果 operator+
被实现为一个成员函数,编译器只允许在第一个参数是一个复数
时考虑重载,并且会隐式转换另一个参数,允许您键入 complex(0,0)+5
。问题是,如果您反转 5+complex(0,0)
的顺序,编译器无法将 5
转换为复数,然后使用成员 operator+
。另一方面,如果您将其作为自由函数提供,编译器将检测到两个参数中的一个在两种情况下都匹配,并将尝试并成功转换另一个参数。最终结果是,通过使用一个自由函数,您可以通过一个实现实现所有这三个添加:complex+complex
、complex+double
、double+complex
(另外对于所有整数和浮点类型,因为它们可以转换为 double
让 operator+
按值获取第一个参数意味着编译器可以在某些情况下省略拷贝:a + b + c
绑定(bind)为 (a+ b) + c
,第一次操作的临时结果可以直接作为第二次调用的参数,不需要额外的复制。
关于c++ - C++ 运算符重载错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6067535/
假设我有一个类,我在其中重载了运算符 == : Class A { ... public: bool operator== (const A &rhs) const; ... };
我知道你不应该使用 std::find(some_map.begin(), some_map.end()) 或 std::lower_bound,因为它会采用线性时间而不是 some_map.lowe
我正在尝试在 Haskell 中定义 Vector3 数据类型,并允许在其上使用 (+) 运算符。我尝试了以下方法: data Vector3 = Vector3 Double Double Doub
我已经为我的类图将运算符重载为“-”。它的用途并不完全直观(糟糕的编码 - 我知道)但是如果我做 graph3 = graph2-graph1 那么图 3 是应该只接收图 2 和图 1 中的那些顶点。
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: Operator overloading 我想重载 以按字母顺序排列字符串,但我不确定该怎么做。 如何再次
下面的代码给我一个编译错误。谁能告诉我为什么? class mytype { public: int value; mytype(int a) { value = a;
这有什么问题吗? class Vec2 attr_accessor :x, :y # ... def += (v) @x += v.x @y += v.y retu
是否可以重载 [] 运算符两次?允许这样的事情:function[3][3](就像在二维数组中一样)。 如果可能的话,我想看看一些示例代码。 最佳答案 您可以重载 operator[] 以返回一个对象
我的团队目前正在与 Lua 合作,创建一个 android 游戏。我们遇到的一件事是表面上无法创建重载构造函数。 我习惯于使用默认值设置一个对象,然后在需要时使其过载。 前任: apples() {
我有一个网页,在某个时候显示一个导航栏,它只不过是一个 a 元素的列表 (ul)。所述 a 元素的大多数样式规则都是通用的。唯一应该改变的部分是要显示的图像,可以从列表中每个 li 元素的 id 标签
我对使用/重载“范围步长”运算符(.. ..)很感兴趣,但我终其一生都无法了解如何使用它。 在文档中它说 // Usage: start .. step .. finish 但是在 F# shell
Java 11(可能无关紧要): public static String toString(Object obj) { return ReflectionToStringBuilder.to
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我无法理解以下代码(针对行号进行注释) class Base { void m1(Object o) { } void m2(String o) { } } publi
我有以下代码片段: #include using namespace std; struct Integer{ int x; Integer(const int val) : x(v
class myclass{ //definitions here }; myclass e; int myarray[10]; /* Do something... */ e = myarray;
为什么不能将下标运算符(operator [])作为 friend 函数重载? 最佳答案 正如Bjarne Stroustrup在D&E book中所说: However, even in the o
我有以下代码片段: #include using namespace std; struct Integer{ int x; Integer(const int val) : x(v
因此,我有一个问题是我最近尝试重载 namespace Eng { /** * A structure to represent pixels */ typedef
如何重载onResume()以正确的方式工作?我想从 activity 返回到 MainActivity ,我希望在其中具有与应用程序启动后相同的状态。我想使用 recreate() 但它循环了或者类
我是一名优秀的程序员,十分优秀!