Есть ли способ объявить объект класса до того, как класс будет создан на C++? Я спрашиваю, потому что я пытаюсь использовать два класса, первый должен иметь в себе экземпляр второго класса, но второй класс также содержит экземпляр первого класса. Я понимаю, что вы можете подумать, что я могу попасть в бесконечный цикл, но на самом деле мне нужно создать и экземпляр второго класса перед первым классом.





Вы не можете объявить экземпляр неопределенного класса, но вы можете объявить указатель одному:
class A; // Declare that we have a class A without defining it yet.
class B
{
public:
A *itemA;
};
class A
{
public:
B *itemB;
};
Это близко к тому, что вы хотите: первый класс содержит второй класс, но второй класс (который должен быть создан первым) просто имеет ссылку на первый класс?
На самом деле я пытаюсь сделать обратное, где первый класс ссылается на второй класс, а второй класс содержит экземпляры первого класса.
Нельзя сделать что-то подобное:
class A {
B b;
};
class B {
A a;
};
Самая очевидная проблема заключается в том, что компилятор не знает, насколько велик он должен создать класс A, потому что размер B зависит от размера A!
Однако вы можете сделать это:
class B; // this is a "forward declaration"
class A {
B *b;
};
class B {
A a;
};
Объявление класса B в качестве предварительного объявления позволяет использовать указатели (и ссылки) на этот класс, не имея еще определения всего класса.
Это называется перекрестной ссылкой. См. Пример здесь.
Там элегантное решение с использованием шаблонов.
template< int T > class BaseTemplate {}; typedef BaseTemplate< 0 > A; typedef BaseTemplate< 1 > B; // A template<> class BaseTemplate< 0 > { public: BaseTemplate() {} // A constructor B getB(); } // B template<> class BaseTemplate< 1 > { public: BaseTemplate() {} // B constructor A getA(); } inline B A::getB() { return A(); } inline A B::getA() { return B(); }This code will work! So, why does it work? The reason has to do with how templates are compiled. Templates delay the creation of function signatures until you actually use the template somewhere. This means that neither getA() nor getB() will have their signatures analyzed until after both classes A and B have already been fully declared. That's the magic of this method.
Интересно (хотя и содержит несколько опечаток). Но getA и getB на самом деле являются фабриками: они возвращают новые экземпляры (по значению). Экземпляр A не имеет B, а экземпляр B не имеет A.
... или ссылку на один: MyClass & rMyObject;