C ++, ссылающийся на создаваемый объект
-
12-09-2019 - |
Вопрос
В 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, но это слишком хрупко, чтобы от него зависеть.