3

私には2つのクラスがあります:

class ClassA {
    public:
        ClassB *classB;
        int i = 100;
}
// and:
class ClassB {
    public:
        void longProcess();
}

ClassB()からvoidを実行します。

ClassA classA = new ClassA();
classA->i = 100;
classA->classB = new ClassB();
classB->longProcess(); // it's a long process!
// but when it will finish - I need to get the "i" variable from ClassA

メソッドlongProcess()から「inti」変数を取得するにはどうすればよいですか?実際、この長いコードを別のスレッドで実行する必要があるため、longProcess()の作業が終了したときに、ClassBから「i」変数を取得する必要があります。助言がありますか?

更新:親クラスへのポインターを保存するためのコードを書こうとしています

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=[ChildClass.h]-=-=-=- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=

#include "ParentClass.h"
class ChildClass {
    public:
        ChildClass();
        ParentClass *pointerToParentClass; // ERROR: ISO C++ forbids declaration of 'ParentClass' with no type
        void tryGet_I_FromParentClass();
};

エラー:ISO C ++は、タイプのない「ParentClass」の宣言を禁止しています

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=[ChildClass.cpp]-=-=-=- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=

#include "ChildClass.h"
ChildClass::ChildClass(){}
void ChildClass::tryGet_I_FromParentClass(){
    // this->pointerToParentClass...??? it's not work
}

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=[ParentClass.h]-=-=-=- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=

#include "ChildClass.h"
class ParentClass {
    public:
        ParentClass();
        ChildClass *childClass;
        int i;
};

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=[ParentClass.cpp]-=-=-=- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=

#include "ParentClass.h"
ParentClass::ParentClass(){
    childClass = new ChildClass();
    childClass->pointerToParentClass = this;
}

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=[MainWindow.cpp]-=-=-=- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=

ParentClass *parentClass = new ParentClass();
4

4 に答える 4

8

thisクラスA(またはそれへの任意のポインター)からクラスB(おそらくコンストラクター内)にポインターを渡す必要があります。これにより、ポインターがどこに含まれているかがわかり、おそらくAへのポインターであるクラスBのメンバーがあります。次に、他の場合と同じようにインスタンスメソッドを呼び出します。

ここには継承がないため、他の例のいくつかは機能しません。

編集:あなたのユーザー名に基づいて、私はあなたがJavaにもっと精通していると思いますか?必要なのは前方宣言です。基本的にこれは次のようになりますChildClass.h

class ParentClass; // Empty
class ChildClass
{
    ParentClass* myParent;
    // Body omitted
}

ChildClass.hが上部に含まれていることを確認しParentClass.h、通常どおりに宣言しParentClass.h、両方の.cppファイルに含めます。また、のすべての実装がChildClass.cppファイルにあり、同じであることを確認してParentClassください(それぞれが独自のものであるかどうかは関係ありません)。

ここで起こっていることは、コンパイラーの循環参照を作成しているということですが、ChildClass.h必要なのは、コンパイラーに「ここにポインターがあります」と伝えることだけです。したがって、クラスの「フルサイズ」は必要ありません。したがって、「空の」前方宣言で十分です。.cppファイルがロールアラウンドするまでに、コンパイラはそれぞれのフルサイズを「認識」し、エラーをスローしません。

詳細については、C++FAQを参照してください。

于 2012-10-10T18:25:48.577 に答える
1

A::callMeWhenLongProcessFinished()が実際にすべての関数から呼び出したい唯一の関数である場合は、オブジェクトへのB::longProcess()ポインタを関数に渡すことができます。A

void B::longProcess(A* object) {
    // long process
    object->callMeWhenLongProcessFinished();
}

設定がそれほど簡単でない場合は、代わりに、適切な関数を呼び出すように設定されたを取得して、代わりにそれを呼び出すことB::longProcess()ができます。std::function<void()>

void B::longProcess(std::function<void()> callback) {
    // long process
    if (callback) {
        callback();
    }
}

void some_function() {
    A* aptr = get_A_object();
    B* bptr = get_B_object();
    bptr->longProcess(std::bind(&A::callMeWhenLongProcessFinished, aptr));
}

異なるスレッドで呼び出しを行うには、適切なスレッドセーフな方法でオブジェクトを送信する必要がありますが、これは完全に別の質問です。

于 2012-10-10T18:32:41.783 に答える
0

子メソッドの最後に親メソッドを呼び出します。

void ClassB::longProcess() {
  // do your processing
  // ...

  callMeWhenLongProcessHasFinished();
}

なんらかの奇妙な理由で変更できない場合longProcessは、2つのメソッドをシリアルに呼び出す別のメソッドを記述します。

于 2012-10-10T18:23:19.030 に答える
0

ClassBが終了するまで、ClassAがそのメソッドを実行しないように、ClassBに参加する必要があります。または、ClassBのメソッドの最後にあるClassAからメソッドを呼び出すだけです。

于 2012-10-10T18:23:29.740 に答える