添加相同类型对象的不同顺序导致错误
Different order of adding same type objects causes an error
谁能解释为什么添加三个这样的对象 a+(a+a)
会导致问题,而 a+a+a
和 (a+a)+a
不会? Foo
class 有一个属性 num
。将两个 Foo
个对象 returns 添加为 num
个值之和。这是我的代码。
main.cpp
#include <iostream>
#include "Foo.h"
using namespace std;
int main()
{
Foo a(4), b;
b = a + a + a; // works fine
cout << a.getNum() << " " << b.getNum() << endl; // outputs "4 12" as it should
b = a + (a + a); // this one causes an error
cout << a.getNum() << " " << b.getNum() << endl;
return 0;
}
Foo.h
#ifndef FOO_H
#define FOO_H
class Foo
{
public:
Foo();
Foo(int a);
Foo operator+(Foo& other);
int getNum();
protected:
private:
int num;
};
#endif // FOO_H
Foo.cpp
Foo::Foo()
{
num = 0;
}
Foo::Foo(int a)
{
num = a;
}
Foo Foo::operator+(Foo& other)
{
Foo tmp = (*this);
tmp.num += other.num;
return tmp;
}
int Foo::getNum()
{
return num;
}
错误消息显示 error: no match for 'operator+' (operand types are 'Foo' and 'Foo')
,即使 + 运算符对于 Foo
类型的操作数已过载。
好的,我知道了。我唯一需要更改的是在 Foo.h
中添加 const
Foo operator+(const Foo& other);
并在 Foo.cpp
Foo Foo::operator+(const Foo& other)
{
Foo tmp = (*this);
tmp.num += other.num;
return tmp;
}
谢谢。
表达式 (a + a)
产生类型 Foo
的纯右值。这种值可以分配给的唯一可能的引用参数类型是 Foo&&
或 Foo const&
。 (a + a) + a
(或不使用括号的等价物)起作用的原因是 non-const 函数可以在纯右值上调用。
在这种情况下,我建议使用 const
版本,但您还应该标记运算符 const
:
class Foo
{
...
Foo operator+(Foo const& other) const;
};
Foo Foo::operator+(Foo const& other) const
{
return num + other.num;
}
可能更可取的是在命名空间范围内实现运算符,这将允许您在 +
的两侧应用从 int
到 Foo
的隐式转换:
class Foo
{
...
friend Foo operator+(Foo const& s1, Foo const& s2)
{
return s1.num + s2.num;
}
...
};
不仅使用此实现
Foo c = a + 1;
有效,而且
Foo d = 1 + a;
谁能解释为什么添加三个这样的对象 a+(a+a)
会导致问题,而 a+a+a
和 (a+a)+a
不会? Foo
class 有一个属性 num
。将两个 Foo
个对象 returns 添加为 num
个值之和。这是我的代码。
main.cpp
#include <iostream>
#include "Foo.h"
using namespace std;
int main()
{
Foo a(4), b;
b = a + a + a; // works fine
cout << a.getNum() << " " << b.getNum() << endl; // outputs "4 12" as it should
b = a + (a + a); // this one causes an error
cout << a.getNum() << " " << b.getNum() << endl;
return 0;
}
Foo.h
#ifndef FOO_H
#define FOO_H
class Foo
{
public:
Foo();
Foo(int a);
Foo operator+(Foo& other);
int getNum();
protected:
private:
int num;
};
#endif // FOO_H
Foo.cpp
Foo::Foo()
{
num = 0;
}
Foo::Foo(int a)
{
num = a;
}
Foo Foo::operator+(Foo& other)
{
Foo tmp = (*this);
tmp.num += other.num;
return tmp;
}
int Foo::getNum()
{
return num;
}
错误消息显示 error: no match for 'operator+' (operand types are 'Foo' and 'Foo')
,即使 + 运算符对于 Foo
类型的操作数已过载。
好的,我知道了。我唯一需要更改的是在 Foo.h
中添加const
Foo operator+(const Foo& other);
并在 Foo.cpp
Foo Foo::operator+(const Foo& other)
{
Foo tmp = (*this);
tmp.num += other.num;
return tmp;
}
谢谢。
表达式 (a + a)
产生类型 Foo
的纯右值。这种值可以分配给的唯一可能的引用参数类型是 Foo&&
或 Foo const&
。 (a + a) + a
(或不使用括号的等价物)起作用的原因是 non-const 函数可以在纯右值上调用。
在这种情况下,我建议使用 const
版本,但您还应该标记运算符 const
:
class Foo
{
...
Foo operator+(Foo const& other) const;
};
Foo Foo::operator+(Foo const& other) const
{
return num + other.num;
}
可能更可取的是在命名空间范围内实现运算符,这将允许您在 +
的两侧应用从 int
到 Foo
的隐式转换:
class Foo
{
...
friend Foo operator+(Foo const& s1, Foo const& s2)
{
return s1.num + s2.num;
}
...
};
不仅使用此实现
Foo c = a + 1;
有效,而且
Foo d = 1 + a;