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) { }

现在我将显示 Buffer 标头:

    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

当您使用作为引用的数据成员创建类时,需要在构造函数初始化程序列表中为该引用分配一个值。

引用在创建时必须被赋予一个值,它们不是指针。它们必须以一个值开头,并且该值不能更改(而该值指向的内容可以更改)。

本质上,您可以将引用视为现有变量的别名。 如果你没有朋友,你不能给朋友起昵称:)

回应评论:

您不会在对象之间“共享引用”。每个对象都有自己对同一个变量的引用。当您“按引用传递”时,您是在告诉编译器您希望函数中的变量实际上是外部范围内的变量,而不是按值创建新变量。这意味着您在一个内存位置只有一个变量。引用只是将您转发到同一内存位置的其他地方的内存。

可以将其视为呼叫转移……我可以在 15 个不同的国家/地区拥有 15 个电话号码。我可以将它们全部设置为将呼叫转移到我在美国的手机。所以,无论他们拨打哪个号码,人们都在给我打电话。

您的每个类都只有另一个引用来将“电话”或变量读/写转发到同一内存位置。因此,您不是在类之间共享引用,而是要确保每个类都具有对相同底层内存位置的引用。

回到比喻,每个班级不会有相同的电话,但每个班级的电话都会转发到相同的号码(变量),这让他们最终都设置/获得相同的值。

回应二:

这是一个简单的例子,让你开始思考,它很容易应用于你的课程。我没有编译它,但它应该可以在减去一两个错字的情况下工作。

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 回答
2

您将指针int*作为第一个参数传递给BufferTypeA,它期望 and int,而您在问题中说您打算使用 a int&。为此, ctorBufferTypeA应该采用 aint&并将其初始化到初始化列表中(即不在{ }ctor 的部分内),例如

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

并且在您的构造中,BufferA您不能传递地址,而是引用,即

int counter;
Buffer = new BufferType(counter);
于 2012-05-29T15:48:29.147 回答
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示例中所示。我的代码版本初始化,如第二个pi示例所示。

于 2012-05-29T15:51:18.037 回答