演算子のオーバーロードとグローバルな演算子のオーバーロード

#include <iostream>
using std::cout; using std::endl;

class CClass {
    int m_num;
public:
    CClass(int num) : m_num(num) {}
    
    bool operator==(const CClass& obj) {
        return m_num == obj.m_num;
    }
    
};

int main () {
    CClass obj1(1);
    CClass obj2(1);
    
    cout << (obj1 == obj2) << endl;
    
    return 0;
}

#include <iostream>
using std::cout; using std::endl;

class CClass {
    int m_num;
public:
    CClass(int num) : m_num(num) {}
    
    friend bool operator==(const CClass& obj1,const CClass& obj2);
};

bool operator==(const CClass& obj1,const CClass& obj2) {
    return obj1.m_num == obj2.m_num;
}

int main () {
    CClass obj1(1);
    CClass obj2(1);
    
    cout << (obj1 == obj2) << endl;
    
    return 0;
}

は結果だけ見ると同じように見えるが内容は異なる。

前者はクラスに演算子オーバーロードの定義していて、後者はグローバルな演算子オーバーロードの定義をしている。

例えば以下のようなコードを書いたときにその違いがわかる。

int main () {
    CClass obj1(1);
    CClass obj2(1);
    
    cout << (obj1.operator==(obj2)) << endl;
    
    return 0;
}

これは前者だとエラーとはならないが、後者だとエラーとなる。

$ cl /W4 /EHsc main.cpp
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for
Copyright (C) Microsoft Corporation.  All rights reserved.

main.cpp
main.cpp(20) : error C2039: '==' : 'CClass' のメンバではありません。
        main.cpp(4) : 'CClass' の宣言を確認してください。

ちなみにクラスに定義するとクラスのサイズが増えたりするだろうか。そう考えるとグローバルに定義した方が良かったりするのかな。