Если один использовать вперед деклараций вместо включает в себя везде, где это возможно?
Нет, явные форвардные декларации не следует рассматривать в качестве общего руководства. Форвардные декларации по сути являются копией и вставкой или кодом с ошибками, который в случае обнаружения ошибки в нем должен быть зафиксирован везде, где используются форвардные декларации. Это может быть подвержено ошибкам.
Чтобы избежать несоответствий между декларациями «вперед» и его определениями, поместите объявления в заголовочный файл и включите этот заголовочный файл как в файлы определения, так и в файлы, содержащие декларацию.
В этом специальном случае, если только непрозрачный класс объявлен вперед, это форвардное объявление может быть в порядке, но в целом «использовать декларации вперед, а не включать, когда это возможно», например название этого нить говорит, может быть довольно рискованно.
Вот некоторые примеры «невидимых рисков» относительно вперед декларации (невидимые риски = декларации несоответствия, которые не обнаруженных компилятором или линкера):
Явные деклараций вперед символов, представляющих данные могут быть небезопасными , так как для таких форвардных объявлений может потребоваться правильное знание размера (размера) данных.
Явные форвардные декларации символов, представляющих функции, также могут быть небезопасными, например, типы параметров и количество параметров.
В приведенном ниже примере показано, это, например, два опасных декларации вперед данных, а также функции:
переменного файла:
#include <iostream>
char data[128][1024];
extern "C" void function(short truncated, const char* forgotten) {
std::cout << "truncated=" << std::hex << truncated
<< ", forgotten=\"" << forgotten << "\"\n";
}
Ьс Файл:
#include <iostream>
extern char data[1280][1024]; // 1st dimension one decade too large
extern "C" void function(int tooLarge); // Wrong 1st type, omitted 2nd param
int main() {
function(0x1234abcd); // In worst case: - No crash!
std::cout << "accessing data[1270][1023]\n";
return (int) data[1270][1023]; // In best case: - Boom !!!!
}
Компиляция программы с g ++ 4.7.1:
> g++ -Wall -pedantic -ansi a.c b.c
Примечание: Invisible опасность, поскольку г ++ не дает никакой компилятор или компоновщик ОШИБКИ/предупреждения
Примечание: Опуская extern "C"
приводит к связующей погрешности для function()
в связи с C++ имя коверкая.
Запуск программы:
> ./a.out
truncated=abcd, forgotten="♀♥♂☺☻"
accessing data[1270][1023]
Segmentation fault
простой ответ, нет. – Nim
Умм - это ответ на вопрос сверху или снизу? – Mat
ваш реальный вопрос (внизу) - AFAIK нет причин не использовать в этом случае форвардную декларацию ... – Nim