Объявить объект еще до того, как этот класс будет создан

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
9
0
10 684
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Вы не можете объявить экземпляр неопределенного класса, но вы можете объявить указатель одному:

class A;  // Declare that we have a class A without defining it yet.

class B
{
public:
    A *itemA;
};

class A
{
public:
    B *itemB;
};

... или ссылку на один: MyClass & rMyObject;

Pat Notz 22.09.2008 10:09

Это близко к тому, что вы хотите: первый класс содержит второй класс, но второй класс (который должен быть создан первым) просто имеет ссылку на первый класс?

На самом деле я пытаюсь сделать обратное, где первый класс ссылается на второй класс, а второй класс содержит экземпляры первого класса.

Matt Pascoe 22.09.2008 18:03
Ответ принят как подходящий

Нельзя сделать что-то подобное:

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.

jwfearn 23.09.2008 04:50

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