运算符重载的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