• 締切済み

クラスのポインタ操作について

CurrentクラスがuQ00の変更に追従できるようにさせたいのですが、うまくいきません。 #include <iostream> using namespace std; class Queue{ public: int id ; Queue* next ; Queue( int id, Queue* next ){ this->id = id ; this->next = next ; } void operator() ( Queue& parent){ next = parent.next ; // これだとuQ00の変更に追従できない // *next = &parent.next ; // これをやるとコンパイルエラー } } ; int main() { Queue Current( -1, NULL) ; Queue uQ00( 0, NULL) ; Queue uQ01( 1, NULL) ; Current( uQ00 ); cout << "CUR A : " << &Current.next      << " D : " << Current.next << endl ; cout << "Q00 A : " << &uQ00.next      << " D : " << uQ00.next << endl ; uQ00.next = &uQ01 ; cout << "CUR A : " << &Current.next      << " D : " << Current.next << endl ; cout << "Q00 A : " << &uQ00.next      << " D : " << uQ00.next << endl ; return 0; } 実行結果: CUR A : 0xbfff8984 D : 0 Q00 A : 0xbfff897c D : 0 CUR A : 0xbfff8984 D : 0 Q00 A : 0xbfff897c D : 0xbfff8970 * CUR DがQ00 Dとイコールにならない *next = &parent.nextとすると以下のコンパイルエラー main.cpp: In member function `void Queue::operator()(Queue&)': main.cpp:15: no match for `Queue& = Queue**' operator main.cpp:5: candidates are: Queue& Queue::operator=(const Queue&) make: *** [main.o] Error 1 以上よろしくお願いします。

みんなの回答

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.3

補足のコードでは例外発生ですよね cが初期化されていないので管理外のメモリーを参照する可能性があります cとbは別アドレスに配置されているのにcへの代入でbが干渉されては困るのではありませんか 配置アドレスが bが0x12345670、cが0x12345674だとすると c = &a;は 0x12345674への代入 b = c; は 0x12345670への代入 ですよね ポインタの中身自体は書き換えられますが ポインタの格納アドレス自体を同一には出来ないと思いますよ 的外れならご容赦ください m(__)m

cafe2cafe
質問者

お礼

ご指摘の通りで補足のコードでは例外が起きます。 ”ポインタの格納アドレス自体を同一にする方法”がないかを考えています。 が言語上無理な気がしてきました。 ありがとうございました。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

まじめにやるなら observer/observable か? 手を抜くなら, もう一発間接参照を入れればできるかも.

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

operator()は void operator() ( Queue& parent){   next = &parent; } なのでは ・・・ class Queueのメンバーnextは次のリスト要素へのポインタですよね parent->nextを代入してしまうと 次の次の要素になってしまいますよ ん? parentってことは引数が親になるんですか子要素でなくて ・・・ だったら parent->next = this; ってことかなぁ

cafe2cafe
質問者

お礼

対応ありがとうございます。 Queueというクラス名は勝手に付けただけでQueueとしての動作を期待してはいません。混乱させてしまい申し訳ありません。 私の疑問は突き詰めていくとC++ではなくCの以下の記述に集約される様で bを完全にcと同じには出来ないか(cを操作するとbも影響を受ける)? になります。 int main(){ int a = 100 ; int* b ; int* c ; b = c ; cout << "B : " << &b << " : " << b << " : " << *b << endl ; cout << "C : " << &c << " : " << c << " : " << *c << endl ; c = &a ; cout << "B : " << &b << " : " << b << " : " << *b << endl ; cout << "C : " << &c << " : " << c << " : " << *c << endl ; return 0; } 基本の基が抜けており申し訳ありません。

関連するQ&A

  • C++のポインタの動作を教えてください

    ちょっと長いですが、ある部分の動作がわかりません そこを詳しく教えてください。 void queue::store(int i)の//リスト末尾に置くっていうところからで なぜ、if(tail)tail->next=item; tail=item; こう書くのかわからないです。 tail->next=itemの次にtail=itemを実行すると、tail->nextの内容も変わるのでは?と思っているのですがどうなっているのかわからないのでお願いします。 説明が下手ですがすみませんが教えてください。 //仮想関数の実例 #include <iostream> #include <cstdlib> #include <cctype> using namespace std; class list{ public: list *head; //リスト先頭へのポインタ list *tail; //リスと末尾へのポインタ list *next; //次項目へのポインタ int num; //格納される値 list(){ head=tail=next=NULL; } virtual void store(int i)=0; virtual int retrieve()=0; }; //キュー型リストの作成 class queue:public list{ public: void store(int i); int retrieve(); }; void queue::store(int i) { list *item; item=new queue; if(!item){ cout << "メモリ割り当てエラー" << endl; exit(1); } item->num=i; //リスト末尾に置く if(tail)tail->next=item; tail=item; item->next=NULL; if(!head)head=tail; } int queue::retrieve() { int i; list *p; if(!head){ cout << "リストは空です" << endl; return 0; } //リスト先頭から取り除く i=head->num; p=head; head=head->next; delete p; return i; } //スタック型リストの作成 class stack:public list{ public: void store(int i); int retrieve(); }; void stack::store(int i) { list *item; item=new stack; if(!item){ cout << "メモリ割り当てエラー" << endl; exit(1); } item->num=i; //スタックのような操作になるよう、リスト最前部におく if(head)item->next=head; head=item; if(!tail)tail=head; } int stack::retrieve() { int i; list *p; if(!head){ cout << "リストは空です" << endl; return 0; } //リスト先頭から取り除く i=head->num; p=head; head=head->next; delete p; return i; } class sorted:public list{ public: void store(int i); int retrieve(); }; void sorted::store(int i) { list *item; list *p,*p2; item=new sorted; if(!item){ cout << "メモリ割り当てエラー" << endl; exit(1); } item->num=i; //次項目のおき場所を見つける p=head; p2=NULL; while(p){ //中へ if(p->num>i){ item->next=p; if(p2)p2->next=item; //先頭要素ではない if(p==head)head=item; //新しい先頭要素 break; } p2=p; p=p->next; } if(!p){ //終わりへ if(tail)tail->next=item; tail=item; item->next=NULL; } if(!head)//先頭要素 head=item; } int sorted::retrieve() { int i; list *p; if(!head){ cout << "リストは空です" << endl; return 0; } //リスト先頭から取り除く i=head->num; p=head; head=head->next; delete p; return i; } int main() { list *p; //キューのデモ queue q_ob; p=&q_ob; //キューをさす p->store(1); p->store(2); p->store(3); cout << "キュー:"; cout << p->retrieve(); cout << p->retrieve(); cout << p->retrieve(); cout << endl; //スタックのデモ stack s_ob; p=&s_ob; //スタックをさす p->store(1); p->store(2); p->store(3); cout << "スタック:"; cout << p->retrieve(); cout << p->retrieve(); cout << p->retrieve(); cout << endl; //ソート済みリストのデモ sorted sorted_ob; p=&sorted_ob; p->store(4); p->store(1); p->store(3); p->store(9); p->store(5); cout << "ソ\ート:"; cout << p->retrieve(); cout << p->retrieve(); cout << p->retrieve(); cout << p->retrieve(); cout << p->retrieve(); cout << endl; return 0; }

  • operator * について

    掛け算ではない方の operator * についての質問です。 下のソースを見てください。関数func()内で、(*this)[idx]というやり方と、直接operator [] を呼び出すやり方を試しています。(*this)[idx]は自分のコピーを作ってしまわないでしょうか?このようなやり方は正しいでしょうか。というのが第1の質問です。 さらに、CTestで operator * を定義していますが、(*this)[idx]で呼び出されません。なぜなのでしょうか。というのが第2の質問です。 どうぞよろしくお願いいたします。 class CTest : public vector<int> { public: CTest() : vector<int>() { push_back(1); push_back(2); push_back(3); } void func() { #if 1 // 質問1 この書き方をしてもコピーが作られないかどうか? cout<<(*this)[0]<<endl; cout<<(*this)[1]<<endl; cout<<(*this)[2]<<endl; #else cout<<operator[](0)<<endl; cout<<operator[](1)<<endl; cout<<operator[](2)<<endl; #endif } CTest& operator * () { // 質問2 なぜこのオペレータが呼び出されないのか cout<<"???"<<endl; return *this; } }; void main(void) { CTest inst; inst.func(); }

  • 添字演算子

    #include <iostream> class hoge{ private: int a; public: hoge(){ a = 0; } int operator+(int fuga){ a = a + fuga; return a; } int operator[](int fuga){ return 1; } }; int main(){ hoge* p; p = new hoge; std::cout << ((*p) + 5) << std::endl; std::cout << ((*p)[1] ) << std::endl; // 5 // 1 // std::cout << ((*p) [] 1); エラーです。何故ですか? }

  • switch文のエラーについて

    次のプログラムを実行したら slect.cpp:In member function `void select::setBlood(std::string)': slect.cpp:16:error: switch quantity not an integer が出ました。switch文の何が不完全ですか?教えてください。 #include<iostream> #include<string> using namespace std; class select { private: string blood; public: void setBlood(string b); void show(); }; void select::setBlood(string b){ blood=b; switch(b){ case 'A': cout<<"A is best"<<endl; break; case 'B': cout<<"B is best"<<endl; break; case 'AB': cout<<"AB is best"<<endl; break; case 'O': cout<<"O is best"<<endl; break; default: cout<<"crazy"<<endl; break; } } void select::show(){ cout<<"Your blood type is :"<<blood<<endl; } int main(){ string b; select Q; cout<<"Please Input your Blood type in A or B or AB or O:"<<endl; cin>>b; Q.setBlood(b); Q.show(); return 0; }

  • VC++でプログラムの勉強をしています。

    プログラムは最近はじめたばかりです。While文とif文を使ってクイズを作ってみたところ、一個目のsinで入力を求めているところから無限ループになってしまいました。色々調べてcin.cler()とsin.ignore()を入れたりもしてみましたが上手くいきませんでした。どこを間違えているのでしょうか? //クイズ #include <iostream> using namespace std; int main()//cin.clear();cin.ignore();???? { int a; int b; while(1) { cout<<"ネコ型のロボットが出てくるアニメといえば?"<<endl; cout<<"A)ドラえもん B)ドラエもん C)ほりえもん D)サザエさん"<<endl; cin>>a; if(a=='A') { cout<<"ファイナルアンサー?"<<endl; cout<<"Y)Yes N)NO"<<endl; cin>>b; if(b=='Y'){break;} if(b=='N'){cout<<"ゆっくり考えてね!!"<<endl;} if(b!='Y'||'N'){cout<<"正しく入力してね!"<<endl;} } if(a=='B'||'C'||'D') { cout<<"ファイナルアンサー?"<<endl; cout<<"Y)Yes N)NO"<<endl; cin>>b; if(b=='Y'){cout<<"残念!!"<<endl;} if(b=='N'){cout<<"ゆっくり考えてね!!"<<endl;} } if(a!='A'||'B'||'C'||'D'){cout<<"正しく入力してね!"<<endl;} } cout<<"正解!!"<<endl; }

  • vectorを使用したときのクラス定義について

    現在C++で、STLのvectorを学習しているのですが、 本を見ると ベクトルに保存されるクラスオブジェクトについて 「"<" および "=="を定義する必要がある」 っと書いてあります。 実際のサンプルなどでは、(長くなってしまってすみません) // ベクトルにクラスオブジェクトを保存する #include <iostream> #include <vector> using namespace std; class Demo { double d; public: Demo() { d = 0.0; } Demo(double x) { d = x; } Demo &operator=(double x) { d = x; return *this; } double getd() { return d; } }; bool operator<(Demo a, Demo b) { return a.getd() < b.getd(); } bool operator==(Demo a, Demo b) { return a.getd() == b.getd(); } int main() { vector<Demo> v; int i; for(i=0; i<10; i++) v.push_back(Demo(i/3.0)); for(i=0; i<v.size(); i++) cout << v[i].getd() << ' '; cout << endl; for(i=0; i<v.size(); i++) v[i] = v[i] .getd() * 2.1; for(i=0; i<v.size(); i++) cout << v[i].getd() << ' '; cout << endl; return 0; } っというように書かれています。 ここで、なぜ<や==演算子をオーバーロードする必要があるのかが わかりません。 VC6.0やbccコンパイラで、演算子のオーバーロード箇所をコメントにしても通ってしまいます。 また、本には、「コンパイラによってはその他の比較演算子の定義も必須とされています」っとあります。 お手数おかけしますが、この辺りのことを簡単に(初心者なので・・・)教えていただけたら。と思います。 よろしくお願いします。

  • BCB6 見せかけのステップ実行!?

    今このように表記しているものを -----xxx.h---------------------------------------- void print( const State& s , const deque<State>& a) { cout << s << endl; for ( size_t i = 0 ; i < a() ; i ++ ) { cout << " " << a[i]; } cout << endl; -------------------------------------------------- ----main.cpp-------------------------------------- while( ! a.empty() { State s = a.front(); a.erase( a.begin() ); print( s ,a); cout << endl; } -------------------------------------------------- sとaの内容をメモリ(配列?)に書き込んで、その内容をButtonを押すごとに1ステップずつ表示したいのですが、どのように表記をしたら画面への出力ではなく、メモリに出力できるのでしょうか。 アドバイス、ご意見ございましたらお返事願います。

  • stringクラスついて

    http://www.kumei.ne.jp/c_lang/cpp/cpp_62.htm この講座にある以下のコード(一部改変)を 実行しようとVisualStudio2005/WinXP環境で cppコンソールアプリケーションとして コンパイルしたところ、エラーが出てコンパイルできませんでした。 色々試行錯誤してみましたが、どうしても上手くいきません。 BorlandC/C++5.5コンパイラでは普通にコンパイルできましたが・・。 ひょっとしてMSのWin32に対応したstringクラスが他に用意されているのでしょうか? #include <iostream> #include <string> using namespace std; int main() { string s, t, u; s = "苗字"; t = "名前"; u = s + t; cout << u << endl; return 0; }

  • coutへの出力内容をプログラム中で取得

    C言語、C++(WinXP)で以下のようなことはできるのでしょうか。 例えば、 //A.cpp void main() { cout << 1 << endl; } というプログラムをA.exeという名前で作ったとします。そして、別のB.exeというプログラムを //B.cpp void main() { system( "A.exe" ); } として実行すると(A.exeとB.exeは同じフォルダにあるとして)、コマンドプロンプトに"1"と出力されますが、B.exe中でA.exeがcoutに出力した内容を取得してなんらかの計算をする、例えば、 //B.cpp void main() { system( "A.exe" ); int x; //xにcoutの内容"1"を取得する x *= 2; } のようなことはできるのでしょうか。また、A.exeの出力先がcoutではなくcerrの場合はどうでしょうか。 coutの場合はリダイレクトを使えば同様のことができるような気もするのですが、実際にやりたいのは、コマンドプロンプトで使う事を前提にして作ったプログラム(A.exeのような)があり、それをVC++6.0で作るダイアログベースのGUIプログラムから呼び出します。ただ、A.exeはエラーがあった場合等にcoutやcerrにメッセージを出力するので、GUIプログラム側でそれを取得してエディットボックスやメッセージボックスに出力したいのです。 このような事ができるのかどうかもわからないのですが、もし方法をご存知でしたらご教授をお願いします。

  • 2つのcppファイルから

    1つのexeファイルを作る必要性が出てきました。 (現在質問中の質問に関連しています。) 例えば file.cpp: #include<iostream> using namespace std; void Output(int x) { cout<<x<<endl; } void main(void) { for(int i=0;i<9;Output(i++)); } をコンパイルリンクすれば済むことを file1.cpp: #include<iostream> using namespace std; void Output(int x) { cout<<x<<endl; } file2.cpp: void main(void) { for(int i=0;i<9;Output(i++)); } という風に分かれているファイルをコンパイルリンクしなければならないのです。 cpp -e file.exe -c file1.cpp -c file2.cpp ではエラーになります。 どうすれば良いのでしょうか?

専門家に質問してみよう