Ограничение объема директив #include - PullRequest
2 голосов
/ 19 февраля 2011

Допустим, у меня есть заголовочный файл с классом, который использует std::string.

#include <string>

class Foo
{
     std::string Bar;

     public:

     // ...
}

Пользователь этого файла заголовка может не захотеть, чтобы std::string был включен в его / ее проект. Итак, как мне ограничить включение только заголовочным файлом?

Ответы [ 4 ]

11 голосов
/ 19 февраля 2011

Пользователь вашего класса должен включать <string>, иначе его компилятор не будет знать, насколько велик объект Foo (и если конструкторы / деструкторы Foo определены встроенными, то компилятор также не будет знать, какой конструктор / деструктор вызывать для члена string).

Это действительно раздражающий побочный эффект модели компиляции C ++ (в основном унаследованной от C). Если вы хотите полностью избежать такого рода вещей, вы, вероятно, захотите взглянуть на PIMPL идиома .

5 голосов
/ 19 февраля 2011

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

Идиоматический способ скрыть такого рода зависимость состоит в том, чтобы полагаться на идиому pimpl.

Тем не менее, почему код, использующий Foo, заботится о том, чтобы <string> был включен?Все его сущности находятся в пространстве имен std (хорошо, за исключением того, что <string> может включать некоторые заголовки стандартной библиотеки C, но обычно вы должны кодировать с ожиданием, что заголовки стандартной библиотеки C могут быть включены любым изЗаголовки стандартной библиотеки C ++).

1 голос
/ 19 февраля 2011

Я не понимаю, как это можно сделать, или если это возможно в C ++.Причина в том, что когда компилятор видит член типа "std :: string", он должен знать, что это за тип, чтобы узнать его размер.Эту информацию можно получить, только просмотрев определение класса в файле .h.

Один из способов, которым пользователи могут использовать другой класс строки в своем источнике, - использование конструкции using:

//This is how users can use an adt with same name but in different namespaces

    using std::string;
    string bar = "there";


    using my_own_lib::string;
    string bar1 = "here";
0 голосов
/ 19 февраля 2011

Вы не можете этого сделать. Если пользователь не хочет включать std::string, то ему или ей вообще не следует использовать этот класс. std::string необходимо будет включить в проект, чтобы правильно связать ваш класс.

...