C++ 継承したクラスのメソッド呼び出し

このQ&Aのポイント
  • C++で継承したクラスのメソッド呼び出しについて質問です。
  • CSuper::Method1()が呼ばれてしまう問題が発生しています。
  • i=1のときにCSub::Method1()を呼び出す方法を教えてください。
回答を見る
  • ベストアンサー

C++ 継承したクラスのメソッド呼び出し

C++で以下のようなコードを組んでいます。 // Class定義 CSuper{ public: Method1(int a); }; CSub : public CSuper{ public: Method1(int a); }; // インスタンス CSuper ins1; CSub ins2; // 管理テーブル struct _table{ int id; CSuper* p; }; // テーブル定義 _table Table[] = { {0, &ins1}, {1, &ins2} }; // 処理 int main(void) { int i; for(i = 0; i < 2; ++i) { Table[i].p->Method1(i); } return 0; } //////////////////////////// このときに、i=1のときは、p = &ins2となるので、 CSub::Method1() が呼ばれることを期待しているのですが、 i=0でもi=1でも、CSuper::Method1() が呼ばれてしまいます。 何か記述が間違っているでしょうか? または、認識が間違っているでしょうか? ご教示のほどよろしくお願いいたします。 環境:依存がないと思っています。 (VC++2008, Cygwin gcc, Fedora4 gcc で確認しましたが同じ結果)

  • darum
  • お礼率38% (7/18)

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

  • ベストアンサー
回答No.1

概ね間違ってはないのですが、「仮想関数」というのを調べると、幸せになれそうな気がします。

darum
質問者

お礼

なるほど! 理解しました。ありがとうございます!!

その他の回答 (2)

回答No.3

C++では、クラスを多相型にするには、メンバー関数をvirtual宣言する必要があります。 Javaだったら、この質問どおりの発想で多相性が実現できます。

darum
質問者

お礼

言語をいろいろかじってる(そして100%は理解できていない)とごちゃごちゃになりますね。 Javaでできるのも思い出しました。 ありがとうございました。

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

期待にそう解決方法は #1 で終わっているので現状の説明: よく struct _table を見てください. その中の p の型はなんですか? そしてその p の型「だけ」を見たとき, Method1 はどれになりますか?

関連するQ&A

  • 「static宣言されているメンバ関数」は、「インスタンスメソッド」な

    「static宣言されているメンバ関数」は、「インスタンスメソッド」なのでしょうか? それとも、「クラスメソッド」なのでしょうか? 先日、下記内容で質問して、その時は分かったつもりだったのですが、 やっぱり分かってなかったようなので、教えてください。 ▽「クラス関数」「メンバ関数」「メソッド」の違いを教えてください。   http://okwave.jp/qa/q5858806.html 例) ▽前提 ・Aクラスのインスタンスa ・static宣言されたpublicメソッド「static_public_method」 ・static宣言されていないpublicメソッド「public_method」 ▽メンバ関数呼び出し ・$a->static_public_method() ・A::static_public_method() ・A::public_method() このとき、「$a->static_public_method()」は、インスタンス経由でアクセスすることになるので、 「インスタンスメソッド」になるのでしょうか。それとも、static(静的)宣言しているので、「クラスメソッド」になるのでしょうか? また、「A::static_public_method()」や、「A::public_method()」は、どちらになるのでしょうか? ※現在、頭の中がこんがらがっているのは、下記3点です。どれかひとつでも構わないので、分かりやすい考え方等あれば、ぜひ教えてください。 ・「static宣言したメンバ関数」は、「インスタンスメソッド」? 「クラスメソッド」? ・「スタティック」宣言してるのに、メンバ関数へ、「->(アロー演算子)」(オブジェクト経由)でアクセスできる理由 ・「A::static_public_method()」と「A::public_method()」の違い

    • ベストアンサー
    • PHP
  • クラスの継承、メソッドのオーバーライド

    ↓の問題が全然わかりません。 問題:サブクラスのsiki2にax2+bx+c=0(b2-4ac>0)とコンストラクタ を定義して、スーパークラスのsiki1にax+b=0とコンストラクタを定義し、解を求めるkaiメソッドを定義する という問題です。途中のプログラムを↓に書きました。 スーパークラス class houteisiki1{ private int kai; private int a; private int b; private int x; //コンストラクタ houteisiki1(int s, int d, int e, int f){ solve=s; a=d; b=e; x=f; } //kaiメソッド kai=(a*x)+b; } サブクラス class houteisiki2 extends houteisiki1{ static int kai(int a, int b, int c, int x){ kai=(a*x*x)+(b*x)+c; if((b*b)+(-4*a*c)>0){ return kai; }else{ println("エラー"); } } } テストクラス class test{ public static void main(string[] args){ ここまで作りましたが、解らなくなりましたので教えてください。 まだ、JAVAを勉強して日が浅いので解りやすく教えてください。

    • ベストアンサー
    • Java
  • 親クラスのポインタで派生クラスの関数呼び出し

    下記のようなクラス構成があるとします。 説明のため簡略化しています。 [Test.h] class CParent { protected: int nParent; public: CParent(){nParent = 10;} ~CParent(){}; virtual int func1(){ // (*1) return nParent; } }; class CSub : public CParent { int m_nSub1; // 派生クラスにしかないメンバ変数 int m_nSub2; // 派生クラスにしかないメンバ変数 public: CSub(){m_nSub = 20;} ~CSub(){}; int func1(){ // (*3) return nParent*2; // 20 } // 派生クラスにしかないメンバ関数 int func2() // (*4) { m_nParent; // 10 return m_nSub1; // 不定値 } int SetData(int n) // (*5) { m_nSub2 = n; return m_nSub2; } }; [Test.cpp] void main() { CParent parent; // 親クラスのオブジェクト CParent* pParent = &parent; // 親クラスのオブジェクトを指すポインタ int nRet = 0; nRet = pParent->func1(); // (*1) // サブクラスのポインタ型にキャストする CSub* pSub = (CSub*)pParent; // (*2) nRet = pSub->func1(); // (*3) nRet = pSub->func2(); // (*4) nRet = pSub->SetData(60); // (*5) } (*3)ではpSubの指すオブジェクトが親クラス(CParent)のため、ポリモーフィズムのメカニズムに従ってCParent::func1()が呼ばれ10が返ってきます。ここまでは想定通りです。 次の(*4)ですが、これはCSub::func2()が呼ばれています。なぜこの呼び出しで子クラスの関数を呼ぶことが出来るのでしょうか? 実際その動作をさせたいのですが、なぜそうなるのかが分かりません。想定ではpSubが指す先は親クラスのため、子クラスにしかないメンバ関数func2()は呼べないはずです。 このコードでは、CSubのコンストラクタは通りませんので(そもそもCSub型のインスタンスは実体化していない)、(*4)の呼び出しでは不定値が返ります。また、(*5)は期待通り動作し、戻り値60が返っています。 これは危険な事をしているのでしょうか? 期待通りではあるのですが、なぜこのような動作になるのか理解できません。 上記のようなことをしたい場合、どのように記述するべきでしょうか?

  • クラスメソッドの仕様

    次のようなクラスメソッドを作りたいのですが、自分で作って見たところ、どのような点を修正すればいいか分かりません。 どうか教えてください。 (1) 次に示す内容を満たすバー(Bar)クラスを作成せよ。 1. バーの右端のx座標(=バーの長さ)、バーの名前を扱う2つのprivateなインスタンス変数を持つ。 2. バーの総数を扱うprivateなクラス変数を持つ。ただし、 ここでいう総数とは、(1)コンストラクタで作成したもの、(2)代入操作で作成したもの、の両方を含む。 3. 引数無しのコンストラクタが呼び出されてバーオブジェクトが作成されると、そのバーのx座標は0以上400未満でランダムに決定され、名前は文字「A」とランダムに決定された0以上10000未満の整数が連接されたものに決定される。 4. バーのx座標を設定するインスタンスメソッドを持つ。 5. バーの名前を設定するインスタンスメソッドを持つ。 6. バーのx座標を取得するインスタンスメソッドを持つ。 7. バーの名前を取得するインスタンスメソッドを持つ。 8. 作成されたバーの総数を取得するクラスメソッドを持つ。 9. 作成されたバーの総数を1増やすクラスメソッドを持つ。 10. 作成されたバーの総数を1減らすクラスメソッドを持つ。 これを自分なりに解釈したところ、 class Bar{ private int x; private String name; private int count; private Bar(){ x=0; count=0; name=""; } public void Bar(){ x = (int)(Math.random()*400); name = "A" + (int)(Math.random()*10000); } public void setBar(int bx){ x=bx; } public void setName(String nm){ name=nm; } public void getX(int bx){ } public void getName(String nm){ } public void getCount(int c){ } } どうか御教授お願いします。

  • C++でこんなクラスを作りたい。

    以下のようなことをしたいと思っています。C++初学者です。 長いかもしれませんがずっと悩んでいます。 いま  w(x) = ap(x) + bq(x) + cr(x) + ..... のような式を計算機実験でメインに扱おうと思っています。 項の数は時によりけりです。 (a,b,cは係数、p,q,rは関数です) それぞれのp,q,rは同じ構造をした式であり、また係数a,b,cを p,q,rの付属物だと考えてcomponentというクラスのインスタンスにしました。 class component{ //メンバ変数 double a //係数 mathvec mu //平均値,mathvecは自作の加減法などができるベクトルのクラス double sigma //分散 //メンバ関数は割愛 } な感じです。 さて、それで上であげたw(x)のような関数が何種類か登場するので 同じ式に属するcomponentのインスタンスをグループ化するようなクラスをつくりたいのです。 w = ap + bq + cr z = ku + mv + ng を扱うのならばとりあえずp,q,r,u,v,gを宣言した跡に mixture mix1(p,q,r); mixture mix2(u,v,g); のようにできるmixtureというクラスを作りたいのです。 それで mix2.at(0)->method(); (u.method()と同じ感じ) みたいな操作ができるとうれしいです。 自分で少し考えたのはmixtureがcomponent*を格納する STLのvectorをもつようにすればいいかなと思いましたが どうもコンパイルエラーがぜんぜん取れず困っております。 class mixture{ private: vector<component *> vec; public: mixture(int num, ...);  //numはp,q,rなどの個数 component *at(int num); //numは何番目の要素を返すか }; mixture::mixture(int num, ...){ va_list ap; va_start(ap,num); for(int i=0;i<num;i++){ vec.push_back(va_arg(ap,component&); } } component* mixture::at(int num){ return vec.at(num); } お願いします! 特にISO C++ forbids declaration of vector with no type みたいなエラーがまず出ます。コンパイラはg++です。

  • 用語の正式名称は?(C++)

    C++のクラスや構造体で、 class TEST { private: int a; //A int func1(); //B protected: int b; //C int func2(); //D public: int c; //E int func3(); //F } struct XXX { int x; //G } というのがあったとします。 //A~//G の正式な読み方はなんでしょうか? たとえば//Bなら、「プライベートメソッド」「プライベートメンバ関数」ですか? ご存知なかた、ご教授おねがいします。 できればその定義が書かれていた出所(URL)もおしえてください。

  • 継承したクラスを、継承元のクラス型の引数に渡すとどうなるのでしょうか?

    継承したクラスを、継承元のクラス型の引数に渡すとどうなるのでしょうか? 以下のようなケースで、 #include "stdio.h" using namespace std; // baseクラス class base { private:  int m_nII;  int m_nJJ;  int m_nKK; public:  base(int i,int j,int k){ m_nII=i; m_nJJ=j; m_nKK=k; }  int GetSum(){ return (m_nII+m_nJJ+m_nKK); } }; // base 継承クラス class hoge : public base { public:  hoge() : base(1,2,3){} }; void func(base* obj){ // baseクラスを引数に取る関数  printf("sum is %d\n", obj->GetSum()); } // main int main(){  hoge objHoge;  func((base*)&objHoge); // <-キャストして渡す  return 0; } として、一応、gccでコンパイルは通り、実行結果も期待通りだったのですが、 このやり方で問題は無いのでしょうか? (たとえば継承先のクラスが独自のメンバを持っていたりなどした場合、期待した結果にならないとか・・) よろしくお願いします。

  • スーパークラスからサブクラスのメソッドを使おうとする、以下のプログラム

    スーパークラスからサブクラスのメソッドを使おうとする、以下のプログラムでつまずいています。 Aを継承したB、Cクラスのインスタンスを作成し、スーパークラスであるA型の配列asにまとめます。 それからループでas[i]にはいっている各インスタンスのメソッドを使いたいのですが、 スーパークラスAにmethod()がないためコンパイルできません、Aにmethod()を作るとA.method()が実行されます。 BとCを同じ配列に保存し、かつそれぞれのmethod()を実行したい場合どのようにしたら良いのでしょうか。 ご教授ください、どうぞよろしくお願いします。 class Main{ private B b; private C c; private A[] as = new A[2]; void mainMethod(){ as[0] = b = new B(); as[1] = c = new C(); for(int i=0; i<3; i++){ as[i].method(); } } } class A{} class B extends A{ void method(){ System.out.print("It is B"); } } class C extends A{ void method(){ System.out.print("It is C"); } }

  • 子クラスのインスタンスから親クラスのインスタンス変数の内容を表示する親クラスのメソッドを叩きたい

    お世話になっております。 rubyのコーディングで疑問が発生しましたので、質問させてください。 以下の様にクラスを定義してあるとします クラスA 体裁を整えて標準出力するクラス  ・インスタンス変数@Aを持つ  ・@Aを元に整形して標準出力する振る舞いを持つ クラスB Aの子クラスで、標準出力する内容を細かく設定するクラス  ・独自のインスタンス変数は持たない  ・親クラスのインスタンス変数@Aを編集する振る舞いを持つ 上記の実装である時、クラスBの振る舞いでクラスAのインスタンス変数@Aを編集しようとした際にエラーが発生します。 尚、レシーバはsuperです。 エラー内容 ./clsb.rb:49:in `edt_dsp': super: no superclass method `edt_dsp' (NoMethodE rror) エラー文中に出てる'edt_dsp'というメソッドが親クラスのインスタンス変数を編集するメソッドです。 尚、子クラスには独自の変数は無いのでinitializeメソッドは定義していません。 なぜこのようなエラーが発生してしまうのかわからず困っています。 現在自分でも色々とサイトを回って調べていますが、解決には至っていません。 ご回答いただければ幸いです。 以上です。よろしくお願いします。

    • ベストアンサー
    • Ruby
  • C言語のプログラム

    以下のプログラムはハッシュテーブルを用いて文字列を探すプログラムなのですが、コンパイル時にセグメントエラーとなってしまいます。プログラム中に誤った箇所があれば教えて頂きたいです。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define HASHSIZE 10 #define MAX_LEN 64 #define N_WORDS 4 struct list { char word [MAX_LEN]; struct list *next; }; struct list *hash_table[HASHSIZE]; char colors[N_WORDS][MAX_LEN] = {"red", "blue", "green", "yellow"}; void my_strcpy(char* a, const char* b) { int i = 0; while(*b != '\0'){ *(a+i) = *(b+i); i++; } *(a+i) = '\0'; } int hash(char *key) { int hashval = 0; while (*key != '\0') { hashval += *key; key++; } return (hashval % HASHSIZE); } int find_word (char *key) { struct list *p; for (p = hash_table[hash(key)]; p != NULL; p++) if (strcmp(key, p->word) == 0) return 1; return 0; } void init_hash_table() { int i, hashvalue; struct list *p, *q; for (i = 0; i < HASHSIZE; i++) { hash_table[i] = NULL; } for (i = 0; i < N_WORDS; i++) { if ((find_word(colors[i])) == 0){ p = (struct list *)malloc(sizeof(struct list)); my_strcpy(p->word, colors[i]); hashvalue = hash(colors[i]); if (hash_table[hashvalue] = NULL) { hash_table[hashvalue] = p; p->next=NULL; } else { q = hash_table[hashvalue]; while (q->next != NULL) q = q->next; q->next = p; p->next=NULL; } } } } void main(void) { init_hash_table(); printf("result = %d\n", find_word("red")); }

専門家に質問してみよう