Перекрестные ссылки включали заголовки в С++-программу
Мне интересен сценарий, подобный приведенному ниже примеру:
Вот код, который будет помещен в файл Header1.h:
#ifndef HEADER1_H
#define HEADER1_H
#include "Header2.h"
class Class1
{
Class2 class2Instance;
};
#endif
Вот код, который будет помещен в файл Header2.h:
#ifndef HEADER2_H
#define HEADER2_H
#include "Header1.h"
class Class2
{
Class1 class1Instance;
};
#endif
Я получаю сообщения об ошибках, когда я это делаю (из-за включений, которые я предполагаю), но мне кажется, что мне нужно будет сделать это, чтобы включить каждый из объектов в отдельные классы. Может ли кто-нибудь помочь мне выполнить это, что я делаю неправильно?
Ответы
Ответ 1
Проблема в том, что размер класса 1 зависит от класса 2 и наоборот. Поэтому нет способа рассчитать размер для одного. Переслать-объявить один из классов и изменить один из атрибутов как указатель или ссылку:
#ifndef HEADER2_H
#define HEADER2_H
class Class1;
class Class2
{
Class1 *class1Instance;
// or
Class1 &class1Instance;
};
#endif
Ответ 2
Файл: header1.h
#ifndef HEADER1_H
#define HEADER1_H
class Class2; // no need to include Header2
class Class1
{
Class2* class2Instance;
}
#endif
Файл: header1.cpp
#include "header2.h" // do include Header2 here, otherwise you will get errors
адаптирован из здесь
Ответ 3
Две структуры бесконечно рекурсируют друг на друга - чтобы знать размер Class1
, вам нужно знать размер Class2
, для которого требуется размер Class1
и т.д. Обходным путем для этого является использование указателя в по крайней мере, один из случаев:
#ifndef HEADER1_H
#define HEADER1_H
class Class2; // no need to include Header2
class Class1
{
Class2* class2Instance;
}
#endif
Ответ 4
Вы не можете иметь класс 2, содержащий экземпляр класса1, и иметь класс 1, содержащий экземпляр класса 2. Вы можете сделать, чтобы каждый класс содержал ссылку или указатель на экземпляр другого типа (с соответствующими прямыми ссылками). то есть.
class Class2;
class Class1
{
Class2& class2Instance;
};
class Class1;
class Class2
{
Class1& class1Instance;
};
Ответ 5
У вас есть классическая циркулярная ссылка. Это уже обсуждалось в разделе "Переполнение стека". Просто примените принятый ответ на этот поток, заменив "struct" для "class", и вы золотой.
Отредактировано для ясности