Ваш класс должен быть автономным и избегать ненужных зависимостей. В вашем примере ваш класс "Compiler" будет зависеть от строки CurrentFileName в течение всего ее существования. Это означает, что если CurrentFileName будет уничтожено до компиляции, у вас возникнет проблема.
Зависимые лица и менеджеры
Итак, я полагаю, это зависит от характера зависимости между классом Dependent и классом it Manager (т.е. класс Dependent зависит от класса Manager, или, в вашем примере, класс Compiler зависит от std :: string класс) ...
- Если зависимость «мягкая», то Dependent должен сделать копию класса Manager.
- Если зависимость "сильная", то у зависимой может быть ссылка на класс Manager.
Мягкий против сильного
Пример "мягкой зависимости" - это когда вашему Зависимому требуется только значение, а не сам объект. Строка обычно рассматривается как значение.
Пример "сильной зависимости" - это когда вашему Зависимому нужен доступ к своему Менеджеру, или когда у Зависимого нет смысла без Менеджера (то есть, если Менеджер уничтожен, тогда все Зависимые должны быть уничтожены раньше) 1017 *
Заключение
Обычно зависимость мягкая.
Если сомневаешься, считай это мягким. У вас будет меньше проблем (это один из способов получить симпатичную ошибку сегмента C ++ без арифметики с указателями), и у вас все еще будет возможность оптимизировать его , если необходимо .
о вашем случае: Soft
Сделайте себе одолжение и сделайте копию стоимости.
Оптимизация - корень всего зла , и, если ваш профилировщик не скажет, что копия строки является проблемой, сделайте копию, как показано ниже:
class Compiler
{
public:
Compiler( const std::string& fileName ); // a reference
~Compiler();
//etc
private:
const std::string m_CurrentFileName; // a value
};
Compiler::Compiler(const std::string& fileName )
: m_CurrentFileName(fileName) // copy of the filename
{
}
О моем случае: Сильный
Теперь вы можете оказаться в ситуации, когда существование Зависимого не имеет смысла без самого менеджера.
В настоящее время я работаю над кодом, где пользователь создает объекты Notifier для подписки на события и извлекает их при необходимости. Объект Notifier прикреплен к Manager при создании и не может быть отсоединен от него.
Выбор дизайна заключается в том, чтобы навязывать пользователю библиотеки менеджер изживает Уведомитель. Это означает следующий код:
Manager manager ;
Notifier notifier(manager) ; // manager is passed as reference
Код Notifier очень похож на код, который вы предложили:
class Notifier
{
public :
Notifier(Manager & manager) : m_manager(manager) {}
private :
Manager & m_manager ;
} ;
Если вы внимательно посмотрите на дизайн, m_manager используется как неизменный указатель на объект Manager. Я использую ссылку C ++, чтобы быть уверенным:
- Ссылка определяется при создании и никогда не будет изменена
- Ссылка никогда не должна быть NULL или недействительной
Это часть контракта.