Есть ли способ объявить объект класса до создания класса на C++? Я спрашиваю, потому что я пытаюсь использовать два класса, первый должен иметь экземпляр второго класса внутри него, но второй класс также содержит экземпляр первого класса. Я понимаю, что вы можете подумать, что я могу попасть в бесконечный цикл, но мне действительно нужно создать и экземпляр второго класса перед первым классом.Объявить объект еще до создания этого класса
ответ
Вы не можете сделать что-то вроде этого:
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, как упреждающее объявление позволяет использовать указатели (и ссылки) на этот класс, не имея еще определение целого класса.
Вы не можете объявить экземпляр неопределенного класса, но вы можете объявить указатель на один:
class A; // Declare that we have a class A without defining it yet.
class B
{
public:
A *itemA;
};
class A
{
public:
B *itemB;
};
Это близко к тому, что вы хотите: Первый класс содержит второй класс, но второй класс (который должен быть создан первым) просто имеет ссылку на первый класс?
Я на самом деле пытаюсь сделать обратное, где первый класс ссылается на второй класс, а второй класс содержит экземпляры первого класса. – 2008-09-22 14:03:04
Это называется перекрестная ссылка. См. Пример here.
Есть an elegant solution с помощью шаблонов.
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(); }
Этот код будет работать! Итак, почему он работает ? Причина связана с тем, как скомпилированы шаблоны . Шаблоны задерживают создание функции подписей, пока вы на самом деле не используете шаблон . Это означает, что ни getA(), ни getB() не будут иметь , их подписи анализируются до тех пор, пока оба класса A и B уже были объявлены . Это волшебство этот метод.
Интересный (хотя он содержит несколько опечаток). Но «getA» и «getB» - действительно фабрики: они возвращают новые экземпляры (по значению). У экземпляра A нет - a B, а экземпляр B - A. – jwfearn 2008-09-23 00:50:11
... или ссылка на один: MyClass & rMyObject; – 2008-09-22 06:09:12