C ++ включает в себя охрану странное поведение? - PullRequest
0 голосов
/ 04 февраля 2019

Я работаю над моим SDL игровым проектом с использованием Ubuntu .Я создал заголовок (объявление) и его файл cpp (определение).И что-то начало меня беспокоить, пожалуйста, пролите немного света.

Что работает и что у меня есть:

(Все 3 файла находятся в одной папке)

motion.h:

#include <SDL2/SDL.h>
class Movement{ ...... };`

motion.cpp:

    #include <SDL2/SDL.h>
    #include "movement.h"
    // Every Definition

main.cpp:

    #include <SDL2/SDL.h>
    #include "movement.h"
    ...... // contents

Компиляция:

$ g++ main.cpp movement.cpp movement.h -lSDL2 -lSDL2_image

Что НЕ СЛЕДУЕТРабота (с включенным охранником):

(я только изменил motion.cpp, остальные остались прежними)

motion.cpp:

#include <SDL2/SDL.h>
#ifndef MOVEMENT_H
#define MOVEMENT_H
...... // contents
#endif

Ошибка: компилятор жалуется, что не может ничего распознатьот motion.hНапример:

......
movement.cpp: At global scope:
movement.cpp:73:6: error: ‘Movement’ has not been declared
......

Мои вопросы:

1) Почему мой включаемый охранник (в movement.cpp) не работает? Я предполагал, что в него будет включен файл motion.h (когда его еще нет).

* Использование include guard для <SDL2/SDL.h> также не работает (компилятор выдаёт ", не был объявлен")." ошибка ).Код выглядит так:

#ifndef SDL2_SDL_H
#define SDL2_SDL_H
......
#endif

2) Почему <SDL2/SDL.h> не нужен охранник включения? Очевидно, что один включен в movement.h, а другой в main.cpp.Не должно ли быть двойное включение ошибка?

1 Ответ

0 голосов
/ 04 февраля 2019

motion.h:

#include <SDL2/SDL.h>
class Movement{ ...... };

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


1) Почему мой включаемый охранник (в motion.cpp) не работает?

motion.cpp:

#include <SDL2/SDL.h>
#ifndef MOVEMENT_H
#define MOVEMENT_H

Исходные файлы никогда не должны включаться в другие файлы, поэтому вам не нужно включать охранник.


Компиляция:

$ g++ main.cpp movement.cpp movement.h -lSDL2 -lSDL2_image
                            ^^^^^^^^^^

Файлы заголовков не нужно компилировать.


2) Почему<SDL2/SDL.h> не нужен защитный щит?

SDL2 / SDL.h имеет защитный щит:

#ifndef SDL_h_
#define SDL_h_

Очевидно, что один включен в motion.h, а другой - в main.cpp.Разве не должно быть ошибки двойного включения?

Нет.Защита заголовка удаляет последнее включение.Вот для чего нужна защита заголовка.

PS Защита заголовка требуется только в том случае, если в заголовке есть определения.Заголовок, который имеет только объявления, не должен иметь охрану.Однако проще использовать защиту заголовков во всех заголовках, чем пытаться выяснить, для каких заголовков они не нужны.

...