Зачем объявлять перенаправленное определение класса в файл cpp? - PullRequest
3 голосов
/ 23 мая 2011

Какой смысл пересылать определение класса в файл .cpp?

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

Есть ли какие-либо преимущества в том, чтобы поместить объявление моего частного класса в файл .cpp, или я должен просто придерживаться своего предварительного объявления в своем открытом class.h и включить мой privateClass.h в файл cpp?

Ответы [ 4 ]

4 голосов
/ 23 мая 2011

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

Если материал находится в публичном заголовке, это будет означать, что публичный заголовок должен будет измениться, если изменилась деталь реализации (в вашем частном классе / структуре). Это плохо, потому что клиентские программы на самом деле нужно будет перекомпилировать (в соответствии с правилом определения ODR - одно определение) и различные последствия, определенные реализацией, для макета класса / vtable и / или искажения имени.

Как только вы сможете избежать зависимости от определения вашего complete частного типа, вы избавитесь от всех ненужных зависимостей, что приведет к

  1. сокращение времени на восстановление
  2. избежать непреднамеренных зависимостей клиентского кода от личных подробностей реализации

Заранее объявленный класс известен как «неполный тип» до тех пор, пока он не будет определен (обычно в частном заголовочном файле или просто в самом файле cpp). До этого момента разрешены только адрес, ссылка, передача по ссылке или передача по указателю. Иногда неполные классы могут привести к сложным семантическим ситуациям; уничтожение объекта для неполного типа будет предполагать не виртуальный деструктор (некоторые компиляторы могут обнаружить это и предупредить, если фактическое определение вводит виртуальный деструктор). Это играет важную роль при определении интеллектуальных указателей на неполные типы, например в популярной языковой фразе. В случае сомнений используйте документацию библиотеки интеллектуальных указателей (например, Boost SmartPtr ).

Обновление Добавление ссылок на backgrounder, так как это получает популярный ответ:

1 голос
/ 23 мая 2011

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

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

1 голос
/ 23 мая 2011

Класс-форвард обычно используется в заголовочном файле. Например:

// Class2.h

class Class1;

class Class2
{
    Class1* m_class1; // Using Class1 type
};

Это позволяет Class2.h использовать Class1 без необходимости включать Class1.h в свой заголовочный файл. Конечно, любой файл .cpp, который включает Class2.h, должен также включать Class1.h.

Просто помните, что вы можете объявлять типы в нескольких модулях, но вы можете определять типы только в одном из них.

1 голос
/ 23 мая 2011

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

...