【发布时间】:2021-06-14 09:23:19
【问题描述】:
为了重载运算符+,我首先将其实现为friend函数+普通函数
class Cents
{
private:
int m_cents;
public:
Cents(int);
int getCents() const;
friend Cents operator+(const Cents&, const Cents&);
};
Cents::Cents(int cents)
: m_cents{cents}
{}
int Cents::getCents() const
{
return m_cents;
}
Cents operator+(const Cents &c1, const Cents &c)
{
return Cents(c1.getCents() + c.getCents());
}
Cents operator+(const Cents &c, int v)
{
return Cents(c.getCents()+v);
}
Cents operator+(int v, const Cents &c)
{
return Cents(v+c.getCents());
}
int main()
{
Cents c1{1};
Cents c2{2};
Cents c{c1+c2};
Cents c3{c+3};
Cents c4{4+c3};
std::cout << c.getCents() << '\n';
std::cout << c3.getCents() << '\n';
std::cout << c4.getCents() << '\n';
return 0;
}
>>>
3
6
10
效果很好。但是当我使用成员函数替换friend 函数时,会引发错误
class Cents
{
private:
int m_cents;
public:
Cents(int);
int getCents() const;
Cents operator+(const Cents&);
};
Cents::Cents(int cents)
: m_cents{cents}
{}
int Cents::getCents() const
{
return m_cents;
}
Cents Cents::operator+(const Cents &c)
{
return Cents(m_cents + c.getCents());
}
Cents operator+(const Cents& c, int v)
{
return Cents(c.getCents()+v);
}
Cents operator+(int v, const Cents& c)
{
return Cents(v+c.getCents());
}
int main()
{
Cents c1{1};
Cents c2{2};
Cents c{c1+c2};
Cents c3{c+3};
Cents c4{4+c3};
std::cout << c.getCents() << '\n';
std::cout << c3.getCents() << '\n';
std::cout << c4.getCents() << '\n';
return 0;
}
>>>
error: invalid operands to binary expression ('int' and 'Cents')
Cents c4{4+c3};
如果 Cents c4{4+c3}; 和 std::cout << c4.getCents() << '\n'; 被删除,其余代码工作正常
int main()
{
Cents c1{1};
Cents c2{2};
Cents c{c1+c2};
Cents c3{c+3};
// Cents c4{4+c3};
std::cout << c.getCents() << '\n';
std::cout << c3.getCents() << '\n';
// std::cout << c4.getCents() << '\n';
return 0;
}
>>>
3
6
我猜这是因为编译器尝试使用成员函数Cents operator+(const Cents&); 解析4+c3,但它不能使用int 来调用该函数。但是为什么编译器不能像使用 Cents operator+(const Cents &c, int v) 对Cents c3{c+3}; 那样使用普通函数Cents operator+(int v, const Cents &c) 来解析4+c3?
---更新---
我在 macOS 上使用 Clion,但是当我使用在线编译器时 https://www.onlinegdb.com/online_c++_compiler 代码(成员函数+普通函数)编译并成功运行。但是在线编译器也会发出警告
About • FAQ • Blog • Terms of Use • Contact Us • GDB Tutorial • Credits • Privacy
© 2016 - 2021 GDB Online
Language
main.cpp
input
main.cpp:54:14: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
main.cpp:38:7: note: candidate 1: Cents operator+(const Cents&, int)
main.cpp:33:7: note: candidate 2: Cents Cents::operator+(const Cents&)
3
6
10
我的后续问题,由于friend 函数和普通函数不需要特定的对象来调用函数,因此它们不会有参数排序问题。当我们在 C++ 中重载运算符时,这是否会让我们更喜欢 friend 函数或普通函数而不是成员函数?
【问题讨论】:
-
你能发布你得到的错误吗?
-
大多数 C++ 专家会告诉您,运算符重载函数的非朋友非成员版本更出色,因为它改进了封装。该函数不需要成为成员即可完成其工作,因此它不应该。
标签: c++ operator-overloading friend-function