Прерывание циклических c ссылок более элегантно в C ++ - PullRequest
0 голосов
/ 13 февраля 2020

Я недавно получил много циклических c зависимостей, когда мои заголовочные файлы включают друг друга. Смотрите также здесь: Что такое предварительные объявления в C ++?

Я на самом деле не совсем понимаю, почему это цикл. Когда компилятор просматривает заголовочный файл файла include, почему он не распознает объявление класса?

Существует ли более элегантный / другой способ разорвать эти циклы вместо прямого объявления другого класса? Мне не нравится, что перед моим текущим классом есть объявление другого класса. Например,

#include "Wheel.h"  // Include Wheel's definition so it can be used in Car.
#include <vector>

class Wheel;

class Car
{
    std::vector<Wheel> wheels;
};

Ответы [ 2 ]

2 голосов
/ 13 февраля 2020

Надеюсь, я понял вашу застрявшую точку.

Чтобы объяснить это, лучше разобраться с точки зрения компилятора.

Компилятор делает для Car.h:

  • Заменяет #include "Wheel.h" его содержимым.
  • Заменяет #include <vector> его содержимым.

На этом шаге единица перевода для Car.h выглядит следующим образом.

class Car;

class Wheel
{
    Car* car;
};

// Vector implementation of the stl goes here

class Car
{
    std::vector<Wheel> wheels;
};

На этом этапе в строке Car* car; необходимо объявление class Car (объявление достаточно для типов указателей) чтобы определить class Wheel, поэтому вам нужно предварительное объявление, потому что вы должны сообщить компилятору, что существует class Car, и он будет определен в ближайшее время.

Если вы закомментируете class Car в строке 1, компилятор не сможет знать, будет ли class Car или нет.

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

На данный момент невозможно найти «более элегантный» способ.

0 голосов
/ 13 февраля 2020

Will может использовать в каждом файле директивы #ifndef ... #define #endif

Таким образом, ваш код станет примерно таким:

#ifndef CAR_H
#define CAR_H
#include "Wheel.h"  // Include Wheel's definition so it can be used in Car.
#include <vector>

class Car
{
    std::vector<Wheel> wheels;
};

#endif

Делайте это во всех ваших файлы заголовков, поэтому каждый файл будет загружен не более одного раза, и циклы больше не будут выполняться

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...