2

私はスレッドクラスのBuffer (独自のクラス) と、 BufferTypeABufferTypeBなどの多くの派生クラスを持っています ...

特定の順序でそれらを同期する必要があるため、特定のタスクを実行する順序を表す整数を指定しています。また、各スレッド Buffer 内で次にタスクを実行するのはどれかを知る必要があるため、すべての BufferType に整数への参照を渡し、それらすべてが共有する必要があり、それをグローバルにしたくありませんでした。

私はいつでも迷子になり、どこにあるのかわかりません。

最初に、クラスからすべての BufferTypes を作成し、その共有整数も次のように定義します。

int currentThreadOrder;

そして、BufferTypes を作成するとき:

int position = 0;
    if (NULL == bufferA) {
            bufferA = new BufferTypeA(&currentThreadOrder, ++position,
                        waitCondition);
        }
        if (NULL == bufferB) {
            bufferB = new BufferPos(&currentThreadOrder, ++position,
                        waitCondition);
        }
        if (NULL == bufferC) {
            bufferC = new BufferRtk(&currentThreadOrder, ++position,
                        waitCondition);
        }

次に、BufferTypeA ヘッダーで:

class BufferTypeA: public Buffer {
public:
    BufferTypeA(int currentThreadOrder,
            int threadConnectionOrder = 0,
            QWaitCondition *waitCondition = NULL);
//..
}

そしてcppファイルで:

BufferTypeA::BufferTypeA(int currentThreadOrder, int threadConnectionOrder, QWaitCondition *waitCondition):
        Buffer(currentThreadOrder, threadConnectionOrder, waitCondition) { }

次に、バッファ ヘッダーを表示します。

    class Buffer: public QThread {
    public:
        Buffer(int &currentThreadOrder,
                int threadConnectionOrder = 0,
                QWaitCondition *waitCondition = NULL);
    //...
protected:
    QWaitCondition *waitCondition;
    int threadConnectionOrder;
    int &currentThreadOrder; // Shared address
    }

そして最後に cpp:

Buffer::Buffer(int &currentThreadOrder, int threadConnectionOrder, QWaitCondition *waitCondition) {

    this->threadConnectionOrder = threadConnectionOrder;
    this->waitCondition = waitCondition;
    this->currentThreadOrder = currentThreadOrder;
}

そして、私が得ているエラーはerror: uninitialized reference member Buffer::currentThreadOrderです。

ポインタとアドレスの単純な問題になるのでお恥ずかしいのですが、どこに問題があるのか​​見当がつかないので、助けてください。

4

3 に答える 3

2

int*への第 1 引数としてポインターをBufferTypeA渡しintますint&。これを行うには、 の ctor はBufferTypeAを取り、int&初期化リストで初期化する必要があります (つまり{ }、ctor の一部内ではありません)。

class BufferType {
  int &Ref;
public:
  BufferTypeA(int& ref) : Ref(ref) { /* ... */ }
};

そして、あなたの構成ではBufferA、アドレスを渡す必要はありませんが、参照、つまり

int counter;
Buffer = new BufferType(counter);
于 2012-05-29T15:48:29.147 に答える
2

参照であるデータ メンバーを持つクラスを作成するときは、参照にコンストラクター初期化子リストの値を割り当てる必要があります。

参照は作成時に値を指定する必要があり、ポインターではありません。それらは値で開始する必要があり、その値は変更できません (その値が指す内容は変更できます)。

基本的に、参照は既存の変数のエイリアスと考えることができます。 友達がいない場合、友達にニックネームを付けることはできません:)

コメントへの応答:

オブジェクト間で「参照を共有」しません。各オブジェクトは、同じ変数への独自の参照を持ちます。「参照渡し」とは、値によって新しい変数を作成するのではなく、関数内の変数を実際に外部スコープ内の変数にすることをコンパイラーに伝えていることを意味します。これは、1 つのメモリ位置に 1 つの変数しかないことを意味します。参照は、同じメモリの場所に転送する他の場所の単なるメモリです。

これを着信転送と考えてください... 15 か国で 15 の電話番号を持つことができます。米国内の私の携帯電話に通話を転送するようにすべて設定できます。ですから、どの番号に電話しても、人々は私に電話をかけてきます。

各クラスには、「電話」または変数の読み取り/書き込みを同じメモリ位置に転送するための別の参照があります。したがって、クラス間で参照を共有しているのではなく、各クラスが同じ基礎となるメモリ位置への参照を持っていることを確認しています。

比喩に戻ると、各クラスの電話は同じではありませんが、各クラスの電話は同じ番号 (変数) に転送されますが、それにもかかわらず、最終的にすべてのクラスが同じ値を設定/取得できるようになります。

応答 II:

これは、理解を深めるための簡単な例です。クラスに適用するのは非常に簡単です。私はそれをコンパイルしませんでしたが、タイプミスがなくても動作するはずです。

class A
{
    public:
        A(int& shared) : m_shared(shared)
        {
            //No actions needed, initializer list initializes
            //reference above. We'll just increment the variable
            //so you can see it's shared in main.
            m_shared += 7;
        }

        void DoSomethingWithIt()
        {
            //Will always reflect value in main no matter which object
            //we are talking about.
            std::cout << m_shared << std::endl;
        }            

    private:

        //Reference variable, must be initialized in 
        //initializer list of constructor or you'll get the same
        //compiler error again.
        int& m_shared;
};

int main()
{
    int my_shared_integer = 0;

    //Create two A instances that share my_shared_integer.
    //Both A's will initialize their internal reference to
    //my_shared_integer as they will take it into their
    //constructors "by reference" (see & in constructor
    //signature) and save it in their initializer list.
    A myFirstA(my_shared_integer);
    A mySecondA(my_shared_integer);

    //Prints 14 as both A's incremented it by 7 in constructors.
    std::cout << my_shared_integer << std::endl;
}
于 2012-05-29T15:44:46.080 に答える
1

次のようなコードが必要です。

Buffer::Buffer(
    int &currentThreadOrder0,
    const int threadConnectionOrder0,
    QWaitCondition *const waitCondition0
) :
  threadConnectionOrder(threadConnectionOrder0),
  waitCondition(waitCondition0),
  currentThreadOrder(currentThreadOrder0)
{}

その理由は、あなたが書けない理由に関連しています

const double pi;
pi = 3.14;

しかし、書くことができます

const double pi = 3.14;

参照は通常、定数ポインターとして実装され、ポインターを初期化した後にアドレスを割り当てることはできません。最初の例のように、コードのバージョンが割り当てpiられます。私のバージョンのコードは、2 番目の例のように初期化piされます。

于 2012-05-29T15:51:18.037 に答える