Що таке заголовок <iosfwd>?


Відповіді:


72

Це означає, що ви можете оголосити у власних заголовках методи, які покладаються на оголошення типів iostream, не маючи необхідності #includeв самих заголовках iostream, які є великими, складними та повільними для компіляції.

Ось простий приклад:

// foo.h
#include <iosfwd>

void sucker(std::iostream& is);

 

// foo.cc
#include <iostream>

void sucker(std::iostream& is) {
    is >> somevar;
}

Чи можете ви пояснити детально, як він пересилає посилання?
wp2

2
@ wp2: Він просто оголошує типи, не визначаючи їх. Чому б самому не заглянути всередину? Він досить маленький.
Марсело Кантос,

1
Що #include <iostream>приносить користь у foo.cc замість того, щоб робити це безпосередньо у foo.h?
wp2

11
@ wp2: Так, але лише у файлі .cpp, який потребує декларації, а не в кожному окремому файлі .cpp, який використовує foo.h.
Марсело Кантос,

Чи є у iosfwd щось, крім простору імен std {class istream; cass ostream; }?
zzz777

39

Як згадував @Marcelo Cantos , це означає, що ви можете включити оголошення класів і функцій iostream, не включаючи повні визначення. У C та C ++ декларація - це твердження, в якому сказано: "ось ім'я чогось (функції / класу / тощо), але я не збираюся розповідати вам більше про це, крім його імені". Для функції це означає назву функції, але не тіло, що містить код функції. Для класу це означає ім'я класу, але не будь-яку змінну або метод-член класу.

І навпаки, визначення - це повне визначення: тіло функції, члени класу тощо.

Часто вам потрібно лише оголошення чогось для використання - у випадку функції, вам не потрібно знати, як виглядає тіло функції, щоб викликати її (за винятком шаблону або вбудованих функцій). Так само, з класом, вам не потрібно знати, які члени класу є, якщо все, що ви робите, - це передавання покажчиків або посилань на екземпляри цього класу. Але як тільки вам потрібно отримати доступ до змінної-члена або викликати метод класу, тоді вам потрібно повне визначення.

Включаючи лише декларації замість визначень, загальний обсяг коду, який компілятор повинен обробити, стає набагато, набагато меншим, а отже компіляція триватиме набагато швидше.

Щоб дати вам уявлення про те, скільки коду обробляється, ось скільки коду міститься в моїй локальній реалізації:

# The following commands create a source file that includes a single header
# file (on stdout), preprocess it with g++ -E, and then count how many lines
# are in the resulting preprocessed output
$ echo '#include <iosfwd>' | g++ -E -xc++ - | wc
    2598    6534   57875
$ echo '#include <iostream>' | g++ -E -xc++ - | wc
   25631   59613  631998

Файл, що включає <iosfwd>, компілятор повинен обробити 2598 рядків коду з різних файлів заголовків, тоді як файл, що включає <iostream>, повинен обробити колосальні 25631 рядки коду. Це перед компіляцією фактичного коду, який вам важливий, у вихідному файлі!


як працює наступна команда, $ echo '#include <iosfwd>' | g ++ -E -xc ++ - | wc Я спробував запустити наступну команду, але вона відображає помилку $ echo '#include <QtGlobal>' | g ++ -E -xc ++ - | wc Де я помилився?
beparas

14

В основному, коли ви використовуєте, <iosfwd>це тому, що ви хочете усунути залежності під час компіляції.

Ви використовуєте <iosfwd>замість традиційних заголовків потоку ( <iostream>та друзів), щоб уникнути включення визначення всього потокового матеріалу. С<iosfwd> ви тільки робите випереджальне оголошення про все потоковому матеріалі.

Я знайшов це посилання особливо корисним: http://www.gotw.ca/gotw/007.htm


3
Яким чином це є більш проникливим, ніж дві вже існуючі та старші за 2 роки відповіді.
Крістіан Рау,

У мене склалося враження, що це більше оптимізація збірки: компіляція займає набагато менше часу, <iosfwd>ніж <iostream>. Або це додаток - основний напрямок того, про що ви говорили?

@ChristianRau, Щоб допомогти вам і гуглерам із відповіддю: для одного (мабуть, принаймні з десяток інших) я справді оцінив стислість цього. Мені не потрібно було нічого з пуху інших, лише магічне слово "переадресація" , яке, як ви, напевно, пропустили, більше ніде не з'явилося на цій сторінці (за винятком тегу запитання, який був доданий після цієї відповіді).
Sz.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.