C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: 基底クラス内から派生クラスのメンバ関数を呼び出す(?)


(過去ログ 49 を表示中)

[トピック内 9 記事 (1 - 9 表示)]  << 0 >>

■27090 / inTopicNo.1)  基底クラス内から派生クラスのメンバ関数を呼び出す(?)
  
□投稿者/ ゆうと (6回)-(2008/10/28(Tue) 00:14:30)

分類:[C/C++] 

お世話になります。ゆうと と申します。
Visual C++ 2008 Express Editionで開発しております。

やりたい事はタイトルのとおり(?)で、基底クラスで宣言した関数ポインタに
派生クラスから派生クラスのメンバ関数を代入して、基底クラスから呼び出したいのです。
やりたい事はこんなかんじです。(スクリプト間違っていたら申し訳ありません<(_ _)>)


class Base {
public:
void (Base::*funcp)();

private:
void Call();
};

void Base::Call()
{
(this->* funcp)();
}

class Derived : public Base {
public:
Derived() //コンストラクタ
{
funcp = &Derived::メンバ関数;
}

};

int main()
{
Derived test;
test.Call();

return(0);
}


どなたかご教授宜しくお願いいたします。
引用返信 編集キー/
■27092 / inTopicNo.2)  Re[1]: 基底クラス内から派生クラスのメンバ関数を呼び出す(?)
□投稿者/ アキラ (115回)-(2008/10/28(Tue) 00:53:38)
アキラ さんの Web サイト
やりたいことが違うかもしれませんが、CRTPという手法を使用して
基本クラスから派生クラスのメンバ関数を呼ぶことはできます。

#include <iostream>

template <class T>
class Base {
public:
    void Call()
    {
        static_cast<T&>(*this).DerivedMember();
    }
};

class Derived : public Base<Derived> {
public:
    void DerivedMember()
    {
        std::cout << "DerivedMember" << std::endl;
    }
};

int main()
{
    Derived d;
    d.Call();
}

引用返信 編集キー/
■27093 / inTopicNo.3)  Re[1]: 基底クラス内から派生クラスのメンバ関数を呼び出す(?)
□投稿者/ Azulean (214回)-(2008/10/28(Tue) 00:58:04)
関数ポインタじゃなくても、仮想関数というものを使うことによって、それらしいことはできるので。

細かい説明は、C++の入門書・参考書をご参照ください。

class Base
{
public:
  virtual void Body() = 0;

// よくよく考えるとCallがprivateだと呼べないよね?
// private:

  void Call()
  {
    Body();
  } 
};

class Derived : public Base
{
public:
  void Body()
  {
    // ここが呼ばれる
  }
};

int main()
{
  Derived test;
  test.Call();
  return 0;
}

引用返信 編集キー/
■27094 / inTopicNo.4)  Re[2]: 基底クラス内から派生クラスのメンバ関数を呼び出す(?)
□投稿者/ アキラ (116回)-(2008/10/28(Tue) 01:08:04)
アキラ さんの Web サイト
2008/10/28(Tue) 01:08:24 編集(投稿者)
いちおう、関数ポインタを使った例です。
Derivedクラスのstaticメンバ関数を呼び出すようにしてます。

#include <iostream>

class Base {
protected:
    void (*funcp)(Base&);

public:
    void Call()
    {
        (*funcp)(*this);
    }
};

class Derived : public Base {
public:
    Derived::Derived()
    {
        funcp = DerivedStaticMember;
    }

    static void DerivedStaticMember(Base& base)
    {
        static_cast<Derived&>(base).DerivedMember();
    }

    void DerivedMember()
    {
        std::cout << "DerivedMember" << std::endl;
    }
};

int main()
{
    Derived d;
    d.Call();
}

引用返信 編集キー/
■27095 / inTopicNo.5)  Re[2]: 基底クラス内から派生クラスのメンバ関数を呼び出す(?)
□投稿者/ アキラ (117回)-(2008/10/28(Tue) 01:08:28)
アキラ さんの Web サイト
2008/10/28(Tue) 01:09:12 編集(投稿者)

二重投稿のため削除
引用返信 編集キー/
■27105 / inTopicNo.6)  Re[1]: 基底クラス内から派生クラスのメンバ関数を呼び出す(?)
□投稿者/ επιστημη (1369回)-(2008/10/28(Tue) 10:28:45)
επιστημη さんの Web サイト
> 派生クラスから派生クラスのメンバ関数を代入して、基底クラスから呼び出したいのです。

メンバ関数ポインタを無理くりcastしてみた。

#include <iostream>

class Base {
public:
  typedef void (Base::*func_type)();
  func_type funcp;
  void Call() { (this->*funcp)(); }
};

class Derived : public Base {
public:
  void f() { std::cout << "Derived::f()\n"; }
  Derived() {
    funcp = static_cast<func_type>(&Derived::f);
  }
};

int main() {
  Derived test;
  test.Call();
}

引用返信 編集キー/
■27111 / inTopicNo.7)  Re[2]: 基底クラス内から派生クラスのメンバ関数を呼び出す(?)
□投稿者/ 774RR (237回)-(2008/10/28(Tue) 11:11:18)
まあ技術的には皆様のご指摘どおりではあるわけだが
# 俺もそういうノリは嫌いではないし

そーいう設計は基本的に汚い。
関数ポインタを陽に使うことを避けるための仮想関数であるわけで、
素直に仮想関数を使うことをお勧めする。

多重継承仮想継承まで話が進んだときに、関数ポインタを陽につかっていると破綻しかねない
(コンパイラに任せておくほうが圧倒的に楽できるわけで)

関数ポインタに入れる値を差し替えることで違う関数が呼べる→
違う派生クラスを生成することで同じ(仮想)関数を呼び出しても違う関数になる
って設計のほうが C++ らしくって後から楽できると思うぞ。
引用返信 編集キー/
■27113 / inTopicNo.8)  Re[3]: 基底クラス内から派生クラスのメンバ関数を呼び出す(?)
□投稿者/ επιστημη (1371回)-(2008/10/28(Tue) 11:20:41)
επιστημη さんの Web サイト
> 関数ポインタに入れる値を差し替えることで違う関数が呼べる→
> 違う派生クラスを生成することで同じ(仮想)関数を呼び出しても違う関数になる
> って設計のほうが C++ らしくって後から楽できると思うぞ。

御意。

関数ポインタは「万策尽きた際の伝家の宝刀」くらいの扱いにしとくが吉かと。

引用返信 編集キー/
■27134 / inTopicNo.9)  Re[4]: 基底クラス内から派生クラスのメンバ関数を呼び出す(?)
□投稿者/ ゆうと (7回)-(2008/10/28(Tue) 19:36:38)
沢山の返信、ありがとうございました<(_ _)>
おかげ様で、無事にやりたいことが出来ました!!

返信して下さった方々の内容は非常にためになるものばかりで、大変勉強になりました。
ここで学んだ事を生かして開発していきたいと思います(^^)ゝ

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


解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -