运算符重载的2种实现方式:
(1) 成员函数(参数少一个)
(2) 非成员函数(如果涉及类中非 public 成员,则需要在类中声明 friend,即友元函数)
1. 成员函数
#include <iostream>
#include <algorithm> // find
#include <vector>
#include <string>
using namespace std;
struct CPerson
{
public:
bool operator==(const CPerson &oPr) // 【1】只需要一个参数
{
return (m_iAge == oPr.m_iAge);
}
public:
int m_iAge;
string m_strName;
};
int main()
{
CPerson oP = {15, "Francis"};
CPerson arroPerson[] = {{19, "Alice"}, {15, "Bob"}, {29, "Mike"}};
CPerson *pP;
// pointer to array element:
pP = std::find (arroPerson, arroPerson+3, oP);
std::cout << "15: " << pP->m_strName << '\n';
std::vector<CPerson> vecP(arroPerson, arroPerson+3);
std::vector<CPerson>::iterator it;
// iterator to vector element:
it = find (vecP.begin(), vecP.end(), oP);
std::cout << "15: " << it->m_strName << '\n';
return 0;
}
2. 非成员函数
#include <iostream>
#include <algorithm> // find
#include <vector>
#include <string>
using namespace std;
struct CPerson
{
int m_iAge;
string m_strName;
};
bool operator==(const CPerson &oPl, const CPerson &oPr)
{
return (oPl.m_iAge == oPr.m_iAge);
}
int main()
{
CPerson oP = {15, "Francis"};
CPerson arroPerson[] = {{19, "Alice"}, {15, "Bob"}, {29, "Mike"}};
CPerson *pP;
// pointer to array element:
pP = std::find (arroPerson, arroPerson+3, oP);
std::cout << "15: " << pP->m_strName << '\n';
std::vector<CPerson> vecP(arroPerson, arroPerson+3);
std::vector<CPerson>::iterator it;
// iterator to vector element:
it = find (vecP.begin(), vecP.end(), oP);
std::cout << "15: " << it->m_strName << '\n';
return 0;
}
说明:运算符重载函数不一定要声明为友元函数,声明为友元函数的目的是获取访问权限,如果涉及的成员全是 public 的,则不需要声明为 friend
3. 原则——何时用成员函数,何时用非成员函数
STL 中 string 对运算符的重载
(1) 成员函数
=, +=
[]
(2) 非成员函数
+
==, !=, >, <, >=, <=
<<, >>
xpression | As member function | As non-member function | Example |
---|---|---|---|
@a | (a).operator@ ( ) | operator@ (a) | !std::cin calls std::cin.operator!() |
a@b | (a).operator@ (b) | operator@ (a, b) | std::cout << 42 calls std::cout.operator<<(int) |
a=b | (a).operator= (b) | cannot be non-member | std::string s; s = "abc"; calls std::string.operator=(const char*) |
a[b] | (a).operator[](b) | cannot be non-member | std::map<int, int> m; m[1] = 2; calls m.operator[](int) |
a-> | (a).operator-> ( ) | cannot be non-member | std::unique_ptr<S> ptr(new S); ptr->bar() calls ptr.operator->() |
a@ | (a).operator@ (0) | operator@ (a, 0) | std::vector<int>::iterator i = v.begin(); i++ calls i.operator++(0) |
摘自:详细规则见:http://en.cppreference.com/w/cpp/language/operators
在此规则基础上,还有一些原则:
(1) 运算符具有可交换性时,重载为非成员函数更合适,如 "+", "=="等;
其它原则待补充
这里有一些其它原则:http://blog.chinaunix.net/uid-21411227-id-1826759.html