• ベストアンサー

Cで多様性を表現するには

こんにちは、あっちこっちとウェブを検索しましたが これと言った答えが見つからないので書かせていただ きます。 C言語で多様性を表現するにはどのようにすればいいで しょうか?関数ポインタを使用すると出来そうだと言 うとこまでは理解したのですが・・・ 以下にJavaで書いたものをCでどうやって表現したら 良いかご教授ください。また、参考になるポインタな どもあれば宜しくお願いします。 public interface MoverIF{  public void run(); } public class Car implements MoverIF{  public Car(){}  public void run(){   System.out.println("Car run");  } } public class Dog implements MoverIF{  public Dog(){}  public void run(){   System.out.println("Dog run");  }  public static void main(String arg){   MoverIF mi[] = new MoverIF[2];   mi[0] = new Dog();   mi[1] = new Car(); for(int i=0;i<2;i++){ mi[i].run();  } }

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

  • ベストアンサー
  • ency
  • ベストアンサー率39% (93/238)
回答No.5

No2、No4 ency です。 No4 の以下の箇所訂正します。 > しかも、ダウンキャストすると~ 誤) ダウンキャスト 正) スーパークラスにキャスト う~ん、何を勘違いしたんだろうか。。。 ダウンキャストはスーパークラスからサブクラスへのキャスト (下向きだから「ダウン」キャスト) のことで、Java だと「ナローイング変換」だったかな? ちなみに、さらに補足しますと、Java のインタフェースは多重に継承させることが可能ですが、この実装ではそれはできません。 # 今回のポリモルフィズムの話とは、直接関係ありませんが。。。 あと、クラスごとにメソッドをテーブル管理すると、メソッドの追加も簡単になりますね。 # 他にもいろいろ案は浮かんできますが、混乱の元になりそうですので、 # このへんでやめておきます。 …と、まあ、そこまでやる必要は果たしてあるのかどうかわかりませんが、C でポリモルフィズムを実現する方法は、考えればいろいろありそうですね。 以上、これまでの回答に対する補足でした。

umepapa05
質問者

お礼

詳細な説明をありがとうございます。 まず今のところは、ここで止めておこうと思います。 まずは、いただいたサンプルを元にリンクリストやらなんやら追加して自分なりの理解を広げようと思います 関数ポインタは使い方が広くて、設計の意図を良く理解してないと混乱しそうですね。オープンソースを読んで読みなれ出来るようにがんばります

すると、全ての回答が全文表示されます。

その他の回答 (4)

  • ency
  • ベストアンサー率39% (93/238)
回答No.4

No2 ency です。 > Cでデザインパターン(構造パターン?)みたいなものがあるもんでしょうか? どうなんでしょうか。。。 たぶんないと思いますけど。。。(?) 「継承」って、スーパークラスのフィールドやらメソッドをサブクラスも持っていることですから、実装レベルでは、サブクラスがスーパークラスのデータ構造を含んでいることになりますよね。 しかも、ダウンキャストするとスーパークラスのメソッドなりフィールドにアクセスできなければなりませんから、スーパークラスのデータ構造はサブクラスの先頭に含んでいることになります。 ということから考えて、No2 ができあがったわけです。 # インタフェースの実装でも、根本は継承といっしょですよね。 あとは、new 相当のものが malloc() だとか、Java には GC があるけど C にはないから C++ で言うところの delete 相当のものが必要だとか…そんな感じでした。

すると、全ての回答が全文表示されます。
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.3

>「cat->mif.run = cat_run;」の部分とか、ほんとにこれでいいのか? 関数のポインタに関数を入れるのは、問題ないと思います。 >Cat* cat = (Cat*)malloc(sizeof(Cat*)); sizeof(Cat*)は、だめでしょう!

umepapa05
質問者

お礼

おはようございます。 >sizeof(Cat*)は、だめでしょう! はい、だめだめでした。sizeof(Cat)でした。 No.2さんが書かれてるように明示的に書いた方がよりよいですね

すると、全ての回答が全文表示されます。
  • ency
  • ベストアンサー率39% (93/238)
回答No.2

こんな感じのもありかなぁ。。。 # わざわざ malloc() する必要もなかったかな。。。 ======================================================== #include <stdio.h> #include <stdlib.h> /*------------------------------------------------ MoverIF インタフェース相当のもの ------------------------------------------------*/ struct MoverIF { void (*run)( void ); }; /*------------------------------------------------ Car クラス相当のもの ------------------------------------------------*/ struct Car { struct MoverIF mover; }; void car_run( void ) { printf( "Car run\n" ); } struct Car *create_car( void ) { struct Car *car; car = malloc( sizeof( struct Car ) ); if ( car != NULL ) { car->mover.run = car_run; } return car; } void delete_car( struct Car *car ) { free( car ); } /*------------------------------------------------ Dog クラス相当のもの ------------------------------------------------*/ struct Dog { struct MoverIF mover; }; void dog_run( void ) { printf( "Dog run\n" ); } struct Dog *create_dog( void ) { struct Dog *dog; dog = malloc( sizeof( struct Dog ) ); if ( dog != NULL ) { dog->mover.run = dog_run; } return dog; } void delete_dog( struct Dog *dog ) { free( dog ); } /*------------------------------------------------ メイン処理 ------------------------------------------------*/ int main( void ) { struct MoverIF *mi[2]; int i; mi[0] = (struct MoverIF*)create_car(); mi[1] = (struct MoverIF*)create_dog(); if ( mi[0] == NULL || mi[1] == NULL ) { printf( "Out of memory!" ); exit(1); } for ( i = 0; i < 2; i++ ) { mi[i]->run(); } delete_car( (struct Car*)mi[0] ); delete_dog( (struct Dog*)mi[1] ); return 0; }

umepapa05
質問者

お礼

ありがとうございます。No.1さんのを自分なりに いじってる間にほぼ同じような解答をいただきまして 大変参考になりました。 自分のソース・・・汚いですね^^; freeもしてないし・・・ 丁寧に書いていただきまして本当にありがとうございます。この機会に色々なアイデアを聞きたいので、こういうのもあるよっと言うのがありましたらお願いします。 Cでデザインパターン(構造パターン?)みたいなものがあるもんでしょうか?

すると、全ての回答が全文表示されます。
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

手抜きだけども、こんな感じ? #include <stdio.h> #include <stdlib.h> typedef struct moveIF { char *className; void (*run)(); } MoveIF; void Dog_run(void){ printf("Dog run\n"); } MoveIF Dog_new(void){ MoveIF a; a.className="Dog"; a.run=Dog_run; return(a); } void Cat_run(void){ printf("Cat run\n"); } MoveIF Cat_new(void){ MoveIF a; a.className="Cat"; a.run=Cat_run; return(a); } void main(void){ MoveIF mi[2]; int i; mi[0] = Dog_new(); mi[1] = Cat_new(); for(i=0;i<2;i++){ (mi[i].run)(); } }

umepapa05
質問者

お礼

夜中にありがとうございます。 参考にしていただきまして、早速自分なりに書いて みました。追記でアドバイス・気になる点がありましたら、お手数ですがお願いします。 特に「cat->mif.run = cat_run;」の部分とか、ほんとにこれでいいのか?って思ってしまうのですが・・ #include <stdio.h> #include <stdlib.h> typedef struct mif{ void (*run)(); }MoveIF; typedef struct dog{ char* name; char* color; char* type; MoveIF mif; }Dog; typedef struct cat{ char* name; char* color; MoveIF mif; }Cat; void cat_run(){ printf("A cat is running\n"); } void dog_run(){ printf("A dog is running\n"); } int main(int argc, char** argv){ MoveIF mi[2]; int i; Cat* cat = (Cat*)malloc(sizeof(Cat*)); Dog* dog = (Dog*)malloc(sizeof(Dog*)); cat->name = "mike"; cat->color= "white"; cat->mif.run = cat_run; dog->name = "poti"; dog->color = "white"; dog->type = "Shiba"; dog->mif.run = dog_run; mi[0] = cat->mif; mi[1] = dog->mif; for(i=0;i<2;i++){ (mi[i].run)(); }     return 0; }

すると、全ての回答が全文表示されます。

関連するQ&A