Вопрос

Можно ли как-нибудь объявить объект класса до того, как класс будет создан на 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;
};

Есть элегантное решение с помощью шаблонов.

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 уже не будут полностью объявлены.Это магия этого метода.

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

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

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