こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

C++

以下にソースを提示します。少々長いことをお許しください。
#include <iostream>
#include <string>
using namespace std;

class Aru{
private:
int data;
public:
Aru(int d): data(d){};
int get_data() const { return data; };

};

class Betu{
private:
Aru *a;
public:
Betu();
~Betu();
Betu (int x);
void input();
void show() const;
int get_data() const { return a->get_data(); }
};

Betu::Betu(int xv):a(0){

a = new Aru(xv);
}

Betu operator+(Betu& aa, const Betu& bb){

int data = aa.get_data() + bb.get_data();
Betu temp(data);
return temp;
}

Betu::Betu():a(0){}

Betu::~Betu(){
delete a;
}

void Betu::input(){
int d;
delete a;
cout << "数字を入力してください" << endl;
cin >> d;
a = new Aru(d);
}

void Betu::show() const{
if(a==0) return ;
cout << "データ:" << get_data() << endl;
}

int main()
{
Betu one;
Betu two;
Betu three;

one.input();
two.input();
three = one + two;
three.show();
}

コンパイルは普通に警告も出ずに通ります。
しかし実行時にエラー・・・・・

まだC++学習のみでエラーを取ることができません。
おそらくoperatorの部分が影響していると思うのですが・・・

ちなみにこのプログラムはoperatorの練習のために作ったプログラムのため、意味のないものになっていますが気にしないでください。
よろしくお願いします。

投稿日時 - 2007-05-19 22:07:50

QNo.3013902

困ってます

質問者が選んだベストアンサー

とりあえず、以下のようにコピー代入演算子を追加して、加算演算子の処理を修正するとOKみたいです。
(環境:C++Builder4)

C++の学習は、こんな短いプログラムを作って動作させながら(エラーを出しながら・・)地道に覚えていくのがいいみたいですね。C++って、マスターするのは大変だけど、その見返りは大きい気がするので、久しぶりに私も、勉強する意欲が出てきます。

class Betu{
private:
Aru *a;
public:
Betu();
~Betu();
Betu (int x);
Betu &operator=(Betu be); //*** add ****

void input();
void show() const;
int get_data() const { return a->get_data(); }
};

Betu operator+(Betu& aa, const Betu& bb){
return Betu(aa.get_data() + bb.get_data());
}

//<<<*** add ************
Betu &Betu::operator=(Betu be){
delete a;
a = new Aru(be.get_data());
return *this;
}
//>>>*** add ************

投稿日時 - 2007-05-20 18:54:21

お礼

返答ありがとうございました。
そして、サンプルソースまで載せていただきありがとうございました。

コピー代入演算子の定義で行ってみたところエラーを取り除くことができました。

エラーの原因はNo1の回答者さんの返答に書いたように、発見できてほっとしています。

現在学生のみですが、学校の授業だと"C++のみ”という授業がありません。C言語ならあるのですがオブジェクト指向は難しいと考えているためでしょうかね?  そのため自分で勉強していく他ないのですが、ある意味では授業で覚えるより個人で何回も練習しているほうが身につくかもしれませんね。かけですけど^^

投稿日時 - 2007-05-20 22:22:10

ANo.3

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(4)

ANo.4

代入演算子は侮れないものがありますね。

例えば lv4u 氏の定義したそれだと

・値渡しで引数を渡しており、しかも使用しているコピーコンストラクタがデフォルトのままなので、問題が発生する可能性がある

・いきなり delete a しているので、new Aru(...) が例外を投げたときに問題が発生する可能性がある

となっており、結構大変です。

投稿日時 - 2007-05-20 19:20:49

お礼

返答ありがとうございました。
今までC言語を勉強し、SDKも学んでいる身ですが、C++は癖がありますね。koko_u_さんがおっしゃられる通り、一番理解しにくいのがこの代入演算子などオペレータを自分で定義する部分です。
自分はなれるために数多く読み、数多く書くことが大事と考えて記述してきましたが、いまだに直感で「ああ、こうか」という域に達しませんorz

解説はごもっともです。
しかし一応解決の1つの方法として考えられるので、例外処理などはのちのち・・・・・

ありがとうございました。

投稿日時 - 2007-05-20 22:32:26

ANo.2

クラス Betuがポインタをメンバー変数として持っていて、その(デフォルト)コンストラクタでメモリ割り当てしているのに、
コピーコンストラクタと代入演算子の定義をしていないからじゃないかな。

投稿日時 - 2007-05-20 00:16:18

お礼

返答ありがとうございました。

エラーが出た理由は初めに回答してくれた方のおかげで理解することができました。

この解決策はsakusaker7さんがおっしゃる通り、コピーコンストラクタと代入演算子の定義が必要になりますね。

ありがとうございました。

投稿日時 - 2007-05-20 22:04:45

ANo.1

+オペレータの中で定義したBetuクラスのローカルオブジェクトが、+オペレータが返り値を返した段階で破棄されているのではないでしょうか。
したがって、showメソッドの中のget_dataメソッドが失敗しているのではないでしょうか。

投稿日時 - 2007-05-19 22:37:12

お礼

返答ありがとうございました。

確かにおっしゃる通りですね・・・
ローカルオブジェクトと値を返したオブジェクトが同じdataをさすことになり、+オペレータが返り値を返した段階でデストラクタが呼ばれローカルオブジェクトは破棄されてしまう。
すると値を返したオブジェクトがdataを参照したとしても、そこにはエラーがないということですね。

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

投稿日時 - 2007-05-20 21:59:23