Вопрос

В C ++ у меня есть ссылка на объект, который хочет указать обратно на своего владельца, но я не могу установить указатель во время построения содержащего класса, потому что его построение не завершено.Итак, я пытаюсь сделать что-то вроде этого:

class A {
   public:

     A() : b(this) {}
   private:
     B b;
};

class B {
   public:
     B(A* _a) : a(_a) {}
   private:
     A* a;
};

Есть ли способ гарантировать, что B всегда инициализируется с помощью A * без A, содержащего указатель на B?

Спасибо

Это было полезно?

Решение

Попробуй это:

class A;

class B {
public:
  B(A *_a) : a(_a) {};

private:
  A* a;
};

class A {
public:
  A() : b(this) {};

private:
  B b;

};

Поскольку B полностью содержится в A, он должен быть объявлен первым.Ему нужен указатель на A, поэтому вы должны переадресовать объявление A перед объявлением B.

Этот код компилируется под более или менее текущие версии g ++.

Другие советы

В C ++ у меня есть ссылка на объект, который хочет указать обратно на своего владельца, но я не могу установить указатель во время построения содержащего класса, потому что его построение не завершено.

Вы можете сохранить указатель в порядке.

Чего вы не можете сделать, так это попытаться добраться до членов / методов A через указатель в конструкторе B, поскольку родительский экземпляр может быть не полностью инициализирован в точке:

#include <iostream>

class Y;

class X
{
    Y* y;
public:
    X(Y* y);
};

class Y
{
    X x;
    int n;
public:
    Y(): x(this), n(42) {}
    int get_n() const { return n; }
};

X::X(Y* p): y(p)
{
    //Now this is illegal:
    //as it is, the n member has not been initialized yet for parent
    //and hence get_n will return garbage
    std::cout << p->get_n() << '\n';
}

int main()
{
    Y y;
}

Если бы вы поменяли местами элементы в Y, чтобы сначала инициализировался n, конструктор X напечатал бы 42, но это слишком хрупко, чтобы от него зависеть.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top