Проблема с использованием этого практического проекта в широком смысле заключается в том, что все, что использует ваш класс, должно будет также импортировать класс декларации вперед.
Я думаю, вы поняли советовать Мэтта: идея заключается в том, чтобы направить, объявить класс вместе с классом, который использует его в своей декларации, так что ваш заголовок остается использовать самостоятельно, не требуя ваших клиентов делать что-нибудь особенное.
Вот краткий пример: допустим, вы хотите использовать класс SingleWidget
в своем классе DoubleWidget
. Однако интерфейс, который предоставляет ваш класс, всегда использует SingleWidget
через указатель или через ссылку; только реализация вызывает методы SingleWidget
. Предложение Мэтта это сделать это
DoubleWidget.h
// Use forward declaration in the header
class SingleWidget;
class DoubleWidget {
SingleWidget &one;
SingleWidget &two;
public:
DoubleWidget(SingleWidget& a, SingleWidget& b) : one(a), two(b) {}
void play();
};
DoubleWidget.cpp
#include "SingleWidget.h"
// Include the header when you cannot avoid including it
#include "DoubleWidget.h"
void DoubleWidget::play() {
one.play();
two.play();
}
вместо этого:
DoubleWidget.h
// Do not include the header where a forward declaration is sufficient
#include "SingleWidget.h"
class DoubleWidget {
SingleWidget &one;
SingleWidget &two;
public:
DoubleWidget(SingleWidget& a, SingleWidget& b) : one(a), two(b) {}
void play();
};
DoubleWid get.cpp
#include "DoubleWidget.h"
void DoubleWidget::play() {
one.play();
two.play();
}
Обратите внимание, что в обоих случаях достаточно для пользователей вашего DoubleWidget
класса включают DoubleWidget.h
заголовок. Однако во втором случае пользователи также получают полное определение класса SingleWidget
, не запрашивая его.
Сокращение сцепления также не имеет смысла, поскольку в силу использования прямого декларирования муфта уже установлена.
У вас есть какая-то связь там, но она очень слабая: ваш класс знает, что существует другой класс, и это все. Напротив, когда вы включаете заголовок, ваш класс знает все о другом классе: он знает его структуру, функции-члены, классы, на которые полагается другой класс, и т. Д. Это хорошая идея не «сбрасывать» всю эту информацию в открытый интерфейс вашего собственного класса.
Спасибо за подробное объяснение.Причина, по которой нам нужно отправить объявление в заголовок, заключается в том, что мы либо возвращаем объект такого типа, либо мы используем свойство этого типа. В любом случае, скорее всего, клиенту потребуется полная информация о типе. Так что, похоже, случай, когда вы хотите использовать форвардную декларацию для минимизации воздействия типа, редко требуется, нет? – Boon
Спасибо за эту заметку. Скажете ли вы тогда * только *, если он предназначен исключительно для среднего человека, что его следует переслать? Если нет, заголовок должен быть объявлен? Проблема, которую я вижу при использовании форвардной декларации на протяжении всего проекта, - это цепная реакция, которую она может вызвать - это означает, что клиенту потенциально придется импортировать несколько заголовков только для использования одной вещи, потому что все, включая свойство свойства и т. Д., Использует форвардную декларацию. – Boon
Я пытаюсь избежать сюрпризов esp в случае, когда я возвращаю объект типа из моего метода. Клиент не сможет использовать его вообще, не импортируя его. Я все еще не получаю коэффициент зависимости, потому что в силу использования прямого объявления зависимость уже установлена. Это не то, что мы используем id. – Boon