C++の関数呼び出しについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
murasame
記事: 4
登録日時: 11年前

C++の関数呼び出しについて

#1

投稿記事 by murasame » 11年前

クラスAとBがあってAはBのインスタンスをポインタで持っている包含関係だとして、
クラスBの関数からクラスAの関数を呼び出すことは出来ないのでしょうか?
C++初学者ゆえ見当違いのことを言っているかもしれません......。
しかし自身がインスタンス化されているもとのクラスの関数を使いたいという状況になった時どうすれば解決できるでしょうか?

アバター
usao
記事: 1889
登録日時: 12年前
連絡を取る:

Re: C++の関数呼び出しについて

#2

投稿記事 by usao » 11年前

こういうことでしょうか?

コード:

//>クラスAとBがあってAはBのインスタンスをポインタで持っている包含関係だとして、
class A
{
public:  //※とりあえず全部publicで書くが
  class B *m_pB;  //B型インスタンスを指し示している
  void Method_of_A();  //なんかメンバ関数
};

//>クラスBの関数からクラスAの関数を呼び出すことは出来ないのでしょうか?
class B
{
public:
  void Method_of_B(){  /* ここでA::Method_of_A() を呼びたい? */  }
};

//
int main()
{
  A a;
  B b;
  A.m_pB = &b;
  ...
  A.m_pB->Method_of_B();
  ...
}
Method_of_A()が普通の(staticでない)メンバ関数であれば,「どのA型インスタンスについて」呼ぶのか?
ということを解決する必要があります.
例えば,クラスBのメンバに A* 型の変数でも追加して,そこにあらかじめ相手を設定しとく とか.
(あるB型のインスタンスbがあったとき,b自身は
 自分がどこでどうやって作られたのか?とか,AのメンバとしてB*があってそのポインタで指し示されてる
 とかいう事情は知らないわけです.その辺のことは大丈夫でしょうか?)

アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前
住所: 東京
連絡を取る:

Re: C++の関数呼び出しについて

#3

投稿記事 by h2so5 » 11年前

クラスBがクラスAのインスタンスを持っている(つまりお互いに包含関係にある場合)は、当然ながらクラスBからAの関数を呼び出し可能です。

しかし、お互いにポインタを持っていなくてもsignal/slotという仕組みを利用する方法もあります。
以下はboost::signals2を使った例です。Bは自分がAのメンバーであることやAのポインタを知りませんが、helpmeというシグナルによってAの関数を間接的に呼び出すことができます。

コード:

#include <iostream>
#include <string>
#include <boost/signals2/signal.hpp>
#include <boost/bind.hpp>

class B {
public:
    void error() {
        helpme("error from class B");
    }
    boost::signals2::signal<void(std::string)> helpme;
};

class A {
public:
    A(B* child) : child_(child) {
        child_->helpme.connect(boost::bind(&A::rescue, this, _1));
    }
    
    void rescue(const std::string& msg) {
        std::cout << "rescue() called: " << msg;    
    }
private:
    B* child_;
};

int main() {
    B b;
    A a(&b);
    b.error();
}
実行結果: http://melpon.org/wandbox/permlink/myx9hpJTIzIocyEc

かずま

Re: C++の関数呼び出しについて

#4

投稿記事 by かずま » 11年前

murasame さんが書きました:クラスAとBがあってAはBのインスタンスをポインタで持っている包含関係だとして、
クラスBの関数からクラスAの関数を呼び出すことは出来ないのでしょうか?
C++初学者ゆえ見当違いのことを言っているかもしれません......。
しかし自身がインスタンス化されているもとのクラスの関数を使いたいという状況になった時どうすれば解決できるでしょうか?
A が B のインスタンスを作り、そのポインタを A が持っていて、
A のメンバ関数から B のメンバ関数を呼び出したとき、
B が「自分を作ってくれた A のインスタンスの関数」を呼び出したい
ということでしょうか?
それなら、B のインスタンスを作るとき、A は自分のインスタンスへの
ポインタ this を B に渡せばよいでしょう。

コード:

#include <iostream>

class B;

class A {
public:
	A();
	void f1();
	void f2();
private:
	B *pB;
};

class B {
public:
	B(A *p);
	void f3();
private:
	A *pA;
};

A::A() { pB = new B(this); }
void A::f1() { std::cout << "A::f1()\n"; pB->f3(); }
void A::f2() { std::cout << "A::f2()\n"; }

B::B(A *p) : pA(p) { }
void B::f3() { std::cout << "B::f3()\n"; pA->f2(); }

int main()
{
	A a;
	a.f1();
}

murasame
記事: 4
登録日時: 11年前

Re: C++の関数呼び出しについて

#5

投稿記事 by murasame » 11年前

みなさんありがとうございます!
まさにこういうことがしたかったのでした!!

閉鎖

“C言語何でも質問掲示板” へ戻る