★演算子オーバーロードの注意点★


それでは、演算子オーバーロードの注意点をいくつか挙げておきます。


注意点1


まず、前々回作ったようなプログラムを書いてみます。

クラスに2つのメンバ変数があり、「+」演算子をオーバーロードして片方のメンバ変数の合計を求め、int型で返すと言うものです。

<sample program cpp063-01>

#include <iostream>

class Sample {
public:

    Sample(const int value1, const int value2);

    int operator+(const Sample &rhs);

private:

    int m_value1;
    int m_value2;
};

int main()
{   
    Sample sample1(3, 5);
    Sample sample2(4, 7);

    int result = sample1 + sample2;

    std::cout << "result = " << result << std::endl;

    return 0;
}

Sample::Sample(const int value1, const int value2) : m_value1(value1), m_value2(value2)
{

}

int Sample::operator+(const Sample &rhs)
{
    return m_value1 + rhs.m_value1;
}

<実行結果>

result = 7
続行するには何かキーを押してください・・・

コンストラクタ関数で初期値を設定し、お互いのメンバ変数m_value1を加算した結果を表示しています。


このクラスに前回作ったような、演算子のオーバーロードを追加したいと思います。

前回のプログラムでは、クラスにある2つのメンバ変数をそれぞれ加算し、結果をクラスとしてまとめて返すように作りました。

色々追加しなければなりませんが、やってみましょう。

<sample program cpp063-02>

#include <iostream>

class Sample {
public:

    Sample();

    Sample(const int value1, const int value2);

    int operator+(const Sample &rhs);

    Sample operator+(const Sample &rhs);

private:

    int m_value1;
    int m_value2;
};

int main()
{   
    Sample sample1(3, 5);
    Sample sample2(4, 7);

    int result = sample1 + sample2;

    std::cout << "result = " << result << std::endl;

    return 0;
}

Sample::Sample() : m_value1(0), m_value2(0)
{

}

Sample::Sample(const int value1, const int value2) : m_value1(value1), m_value2(value2)
{

}

int Sample::operator+(const Sample &rhs)
{
    return m_value1 + rhs.m_value1;
}

Sample Sample::operator+(const Sample &rhs)
{
    Sample temp;

    temp.m_value1 = m_value1 + rhs.m_value1;
    temp.m_value2 = m_value2 + rhs.m_value2;

    return temp;
}

<コンパイル結果>

error C2556: 'Sample Sample::operator +(const Sample &)': オーバーロード関数は、'int Sample::operator +(const Sample &)' と戻り値の型のみが異なります。
note: 'Sample::operator +' の宣言を確認してください
error C2371: 'Sample::operator +': 再定義されています。異なる基本型です。
note: 'Sample::operator +' の宣言を確認してください
error C2264: 'Sample::operator +': 関数宣言か定義にエラーがあるので、関数が呼び出せません。
error C2088: '+': class に対して正しくありません。
error C2556: 'Sample Sample::operator +(const Sample &)': オーバーロード関数は、'int Sample::operator +(const Sample &)' と戻り値の型のみが異なります。
note: 'Sample::operator +' の宣言を確認してください
error C2371: 'Sample::operator +': 再定義されています。異なる基本型です。
note: 'Sample::operator +' の宣言を確認してください
error C2084: 関数 'int Sample::operator +(const Sample &)' は既に本体を持っています。
note: '+' の以前の定義を確認してください

コンパイルエラーになりました・・・

演算子オーバーロードも「オーバーロード」ですから、引数の数や型でどの演算子を使うか判断しています。

今回のエラーは、

int operator+(const Sample &rhs);

Sample operator+(const Sample &rhs);

この2つの引数が全く同じですから、区別が付かないのが原因です。


注意点2


次の注意点は前にも書きましたが、その演算子でイメージ出来ない内容の関数を作ってはいけない、と言う事です。

<sample program cpp063-03>

#include <iostream>

class Sample {
public:

    Sample(const int value1, const int value2);

    int operator+(const Sample &rhs) const;

private:

    int m_value1;
    int m_value2;
};

int main()
{   
    Sample sample1(3, 5);
    Sample sample2(4, 7);

    int result = sample1 + sample2;

    std::cout << "result = " << result << std::endl;

    return 0;
}

Sample::Sample(const int value1, const int value2) : m_value1(value1), m_value2(value2)
{

}

int Sample::operator+(const Sample &rhs) const
{
    return m_value1 - rhs.m_value1;
}

<実行結果>

result = -1
続行するには何かキーを押してください・・・

「+」演算子をオーバーロードしているのに、中身は減算をしています。

このようなオーバーロードは絶対にすべきではありません。


注意点3


次の例を書きましょう。

↓に一番最初のプログラムがあります。

<sample program cpp063-01>

#include <iostream>

class Sample {
public:

    Sample(const int value1, const int value2);

    int operator+(const Sample &rhs);

private:

    int m_value1;
    int m_value2;
};

int main()
{   
    Sample sample1(3, 5);
    Sample sample2(4, 7);

    int result = sample1 + sample2;

    std::cout << "result = " << result << std::endl;

    return 0;
}

Sample::Sample(const int value1, const int value2) : m_value1(value1), m_value2(value2)
{

}

int Sample::operator+(const Sample &rhs)
{
    return m_value1 + rhs.m_value1;
}

<実行結果>

result = 7
続行するには何かキーを押してください・・・

これはメンバ変数m_value1を加算する演算子オーバーロードです。

ここにメンバ変数m_value2を加算する演算子オーバーロードを追加したいと考えました。

プロトタイプ宣言を考えると、

int operator+(const Sample &rhs);

と、すでにある演算子オーバーロードと全く同じです。

こう言った場合、演算子オーバーロードでの対処方法はありません!

あきらめて、メンバ関数で対応してください。


次へ

戻る

目次へ