#c #data-structures #vector #struct #initialization
#c #структуры данных #вектор #структура #инициализация
Вопрос:
У меня есть структура, объявленная следующим образом:
#ifndef PLAYLIST_H
#define PLAYLIST_H
#include <iostream>
#include <string>
#include <vector>
#include "playlistitem.h"
#include "song.h"
#include "time.h"
struct Playlist {
std::vector<Song> songs;
Time cdTotalTime;
int totalTime;
};
и структурная композиция, объявленная в другом файле:
#ifndef SONG_H
#define SONG_H
#include "playlist.h"
#include "time.h"
struct Song {
std::string title;
std::string artist;
std::string album;
int track;
Time length;
};
У меня есть оба определения структуры в заголовках, и оба #включены, как и должны быть.
При компиляции я получаю ошибку в
std:vector<Song> songs;
ошибка ‘Song’ не была объявлена в этой области
Чего мне не хватает?
Комментарии:
1. Вы уверены, что включили
Song
файл определения в файл, определяющийPlaylist
? И что это в том же пространстве имен?2. Как вы «включаете их так, как они должны быть»? (Подсказка: это не так 😉 )
3. Пожалуйста, покажите нам файл, в котором вы используете определения.
Ответ №1:
playlist.h включает song.h
song.h НЕ должен включать playlist.h
Защита заголовка предотвращает бесконечную рекурсию, они не исправляют циклические зависимости.
В настоящее время song.h включает playlist.h. Затем, когда playlist.h включает song.h, ничего не происходит (из-за защиты заголовка) и Song
не определяется. Таким образом, playlist.h выдает ошибки.
Ответ №2:
Не только ваш основной файл, но и файл, в котором Playlist
объявлен, также должен #включать файл, в котором Song
находится.
Ответ №3:
Определение Song
должно предшествовать его использованию в определении Playlist
. Поскольку они находятся в разных заголовках, вы должны убедиться, что заголовок для Playlist
включает в себя заголовок Song
, и оба имеют надлежащие заголовочные ограждения.
Ответ №4:
Ваши заголовки включают друг друга циклическим образом. Это бесполезно и ненужно. Почему вы song.h
включаете playlist.h
? Удалите #include "playlist.h"
из song.h
, и это должно исправить ошибку.
Ответ №5:
Вы могли бы создать прототип Song
в своем заголовке, поместив struct Song;
и просто включив заголовок в свой.c/.cpp файл. Это дает бонус в виде более быстрого времени компиляции! 😀
Рекурсивные включения отлично работают с защитой включения, если вы правильно их расположите. Я всегда стараюсь включать наименьшее количество заголовков в файлы .h, оставляя их для исходных файлов.
Кроме того, я не вижу #endif в вашем коде. Прямо сейчас я предполагаю, что ваш код действительно имеет это;)