演算子のオーバーロード

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
レフェリア
記事: 33
登録日時: 11年前

演算子のオーバーロード

#1

投稿記事 by レフェリア » 11年前

分数を[ 1/2 ]の形で2回入力したらそれを加算・減算・乗算・除算し、
その答えを表示するプログラムを作ろうとしたのですが四則演算の演算子のオーバーロードが
うまくいきません。
クラス部のコードを乗せるので、アドバイスをお願いします。

コード:

class Bunsu
{
	int bunshi;		//分子
	int bunbo;		//分母

public:

	//デフォルトコンストラクタ
	Bunsu()
	{
		bunshi = 1;
		bunbo = 0;
	}

	//コンストラクタ
	Bunsu( int b1, int b2 )
	{
		//約分をする
		yakubun( b1, b2 );
	}

	//出力
	void p_bunsu(void)
	{
		cout << get_bunshi() << " / " << get_bunbo() << "\n";
	}

	//分子の値を返す
	int get_bunshi(void)
	{
		return bunshi;
	}

	//分母の値を返す
	int get_bunbo(void)
	{
		return bunbo;
	}

	//分子に代入
	void set_bunshi(int b)
	{
		bunshi = b;
	}

	//分子に代入
	void set_bunbo(int b)
	{
		bunbo = b;
	}

	//約分をする
	void yakubun( int si, int bo )
	{
		int yaku;

		//最大公約数から約分をできるかを判定
		if( bo > si )
			yaku = gcm( bo , si );
		else
			yaku = gcm( si , bo );
		
		if( yaku != 0 )
		{
			bunbo = bo / yaku;
			bunshi = si / yaku;
		}
	}

	//出力用のメンバ関数 (出力演算子のオーバーロード)
	friend ostream& operator<<( ostream& , Bunsu&  );

	//入力用のメンバ関数 (入力演算子のオーバーロード)
	friend istream& operator>>( istream& , Bunsu&  );

	//加算用のメンバ関数
	friend Bunsu operator+( const Bunsu&  );

	//減算用のメンバ関数
	friend Bunsu operator-( const Bunsu&  );

	//掛算用のメンバ関数
	friend Bunsu operator*( const Bunsu&  );

	//除算用のメンバ関数
	friend Bunsu operator/( const Bunsu&  );
};

//最大公約数をユークリッドの互助法で求める関数
int gcm( int x, int y )	
{
	int r;
	while( y != 0 )	//yの値が0以外のときに中でループを続ける
	{
		r = x % y;
		x = y;
		y = r;
	}
	return x;
}

ostream& operator<< ( ostream& s, Bunsu& a)
{

	s << a.bunshi << " / " << a.bunbo << "\n";

	return s;
}

istream& operator>> ( istream& i, Bunsu& d )
{
	char ch;

	i >> d.bunshi >> ch >> d.bunbo;

	return i;
}

//加算用のメンバ関数
Bunsu operator+( const Bunsu& a );
{
	Bunsu tmp;
	tmp.bunshi = bunshi + a.bunshi;
	tmp.bunbo = bunbo + a.bunbo;
	return tmp;
}

//減算用のメンバ関数
Bunsu operator-( const Bunsu& a );
{
	Bunsu tmp;
	tmp.bunshi = bunshi - a.bunshi;
	tmp.bunbo = bunbo - a.bunbo;
	return tmp;
}

//掛算用のメンバ関数
Bunsu operator*( const Bunsu& a );
{
	Bunsu tmp;
	tmp.bunshi = bunshi * a.bunshi;
	tmp.bunbo = bunbo * a.bunbo;
	return tmp;
}

//除算用のメンバ関数
Bunsu operator/( const Bunsu& a );
{
	Bunsu tmp;
	tmp.bunshi = bunshi / a.bunshi;
	tmp.bunbo = bunbo / a.bunbo;
	return tmp;
}
あと、四則演算子の関数内のコードは一応書いているだけです。

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: 演算子のオーバーロード

#2

投稿記事 by h2so5 » 11年前

どのように上手くいかないかを書いてください。

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: 演算子のオーバーロード

#3

投稿記事 by h2so5 » 11年前

とりあえずコンパイルは通るようにしてみました。
オペレーターオーバーロード以前にC++の文法として間違っているところがたくさんあるのでよく確認してください。

コード:

#include <iostream>

using namespace std;

class Bunsu
{
    int bunshi;     //分子
    int bunbo;      //分母
 
public:
 
    //デフォルトコンストラクタ
    Bunsu() :
        bunshi( 1 ),
        bunbo( 0 )
    {
    }
 
    //コンストラクタ
    Bunsu( int b1, int b2 )
    {
        //約分をする
        yakubun( b1, b2 );
    }
 
    //出力
    void p_bunsu(void) const
    {
        cout << get_bunshi() << " / " << get_bunbo() << "\n";
    }
 
    //分子の値を返す
    int get_bunshi(void) const
    {
        return bunshi;
    }
 
    //分母の値を返す
    int get_bunbo(void) const
    {
        return bunbo;
    }
 
    //分子に代入
    void set_bunshi(int b)
    {
        bunshi = b;
    }
 
    //分子に代入
    void set_bunbo(int b)
    {
        bunbo = b;
    }
 
    //約分をする
    void yakubun( int si, int bo )
    {
        int yaku;
 
        //最大公約数から約分をできるかを判定
        if( bo > si )
            yaku = gcm( bo , si );
        else
            yaku = gcm( si , bo );
        
        if( yaku != 0 )
        {
            bunbo = bo / yaku;
            bunshi = si / yaku;
        }
    }
 
    //出力用のメンバ関数 (出力演算子のオーバーロード)
    ostream& operator<<( ostream& ) const;
 
    //入力用のメンバ関数 (入力演算子のオーバーロード)
    istream& operator>>( istream& );
 
    //加算用のメンバ関数
    Bunsu operator+( const Bunsu&  );
 
    //減算用のメンバ関数
    Bunsu operator-( const Bunsu&  );
 
    //掛算用のメンバ関数
    Bunsu operator*( const Bunsu&  );
 
    //除算用のメンバ関数
    Bunsu operator/( const Bunsu&  );
    
private:
    
    //最大公約数をユークリッドの互助法で求める関数
    int gcm( int x, int y );
};
 
//最大公約数をユークリッドの互助法で求める関数
int Bunsu::gcm( int x, int y ) 
{
    int r;
    while( y != 0 ) //yの値が0以外のときに中でループを続ける
    {
        r = x % y;
        x = y;
        y = r;
    }
    return x;
}
 
ostream& Bunsu::operator<< ( ostream& s ) const
{
 
    s << bunshi << " / " << bunbo << "\n";
 
    return s;
}
 
istream& Bunsu::operator>> ( istream& i )
{
    char ch;
 
    i >> bunshi >> ch >> bunbo;
 
    return i;
}
 
//加算用のメンバ関数
Bunsu Bunsu::operator+( const Bunsu& a )
{
    Bunsu tmp;
    tmp.bunshi = bunshi + a.bunshi;
    tmp.bunbo = bunbo + a.bunbo;
    return tmp;
}
 
//減算用のメンバ関数
Bunsu Bunsu::operator-( const Bunsu& a )
{
    Bunsu tmp;
    tmp.bunshi = bunshi - a.bunshi;
    tmp.bunbo = bunbo - a.bunbo;
    return tmp;
}
 
//掛算用のメンバ関数
Bunsu Bunsu::operator*( const Bunsu& a )
{
    Bunsu tmp;
    tmp.bunshi = bunshi * a.bunshi;
    tmp.bunbo = bunbo * a.bunbo;
    return tmp;
}
 
//除算用のメンバ関数
Bunsu Bunsu::operator/( const Bunsu& a )
{
    Bunsu tmp;
    tmp.bunshi = bunshi / a.bunshi;
    tmp.bunbo = bunbo / a.bunbo;
    return tmp;
}

int main() {
	
	return 0;
}

レフェリア
記事: 33
登録日時: 11年前

Re: 演算子のオーバーロード

#4

投稿記事 by レフェリア » 11年前

h2so5さんありがとうございます<(_ _)>

<< や + などの演算子をfriend関数での定義に書き換えようと思っているのですが、
そのまま
friend Bunsu operator-( const Bunsu& );
このように前に書くだけでよいのでしょうか?

レフェリア
記事: 33
登録日時: 11年前

Re: 演算子のオーバーロード

#5

投稿記事 by レフェリア » 11年前

friend関数を修正前のコードでは入力していたのですが、2項演算子のオーバーロード部で
エラーがいろいろと発生しています。
私自身色々とコードを変更したりはしているのですがなかなかうまくいきません。
解決法を教えてもらえませんか?

よろしくお願いします。<(_ _)>

アバター
GRAM
記事: 164
登録日時: 13年前
住所: 大阪

Re: 演算子のオーバーロード

#6

投稿記事 by GRAM » 11年前

レフェリア さんが書きました:h2so5さんありがとうございます<(_ _)>

<< や + などの演算子をfriend関数での定義に書き換えようと思っているのですが、
そのまま
friend Bunsu operator-( const Bunsu& );
このように前に書くだけでよいのでしょうか?
Bunsu operator-( const Bunsu& );これはメンバ関数であって非メンバ関数ではないのでfriendのしようがないのではないとおもいますが。
書くとしたら
friend const Bunsu operator-( const Bunsu& lhs, const Bunsu& rhs );
のように両オペランドを引数にとるものをfriendにするしかないと思います。

ちなみにどうせだから書きますが、
この関数はfriendにする必要がありません。
メンバ関数のoperator-=をオーバーロードして、

コード:

const Bunsu operator-( Bunsu lhs, const Bunsu& rhs  )
{
    lhs -= rhs;
    return lhs; 
}
で済みます。
ちなみに戻り値をBunsuでなくconst Bunsuにしたのは(a-b) = cという構文をエラーにするためです
(当然基本型ならエラーになります)

※ところで+とか-とかの演算はそれで正しいのですか?
※gcmはx>yが保障されていますか?
※gcmは本当にメンバ関数である必要がありますか?

レフェリア
記事: 33
登録日時: 11年前

Re: 演算子のオーバーロード

#7

投稿記事 by レフェリア » 11年前

GRAMさんありがとうございます<(_ _)>

>※ところで+とか-とかの演算はそれで正しいのですか?
演算内容に関してはとりあえず書いているだけで実際に使う場合は内容を分数の足し算・引き算を行うコードになります。

>※gcmはx>yが保障されていますか?
gcmは約分を行う場合のみ呼び出し、処理を行うようにプログラムを書いています。
また、呼び出し時

コード:

if( x > y )
 gcm(x,y);
else
 gcm(y,x);
といった風にgcm内で x>y を保障できるようにしています。

>※gcmは本当にメンバ関数である必要がありますか?
必要がないと思います。
修正前のコードでは単なる関数として記述していました。
位置的な問題で、自分でもメンバ関数だと勘違いしていたかもしれません(^^;

レフェリア
記事: 33
登録日時: 11年前

Re: 演算子のオーバーロード

#8

投稿記事 by レフェリア » 11年前

解決できました。

ご協力ありがとうございました!

閉鎖

“C言語何でも質問掲示板” へ戻る