Подтвердить что ты не робот

Каков предпочтительный способ реализации метода factory в С++?

Вопрос с новичком: у меня есть иерархия классов с некоторыми виртуальными функциями, и я пытаюсь реализовать метод factory, но я не уверен, что это лучший способ:

  • Возвращает необработанный указатель из метода factory и переносит его в интеллектуальный указатель в вызывающем методе
  • Вернуть умный указатель из factory
  • Вернуть правильный объект из factory (но он собирается скопировать производный класс правильно?) и назначить его локальному объекту в вызывающем методе
  • Вернуть ссылку из factory (но как создать объект в методе factory без утечки памяти?)

Буду признателен за пример метода factory и минимального клиента, который эффективен и не утечка памяти.

Мой фон - это С# и Java, поэтому я немного потерял управление памятью в С++ atm.

4b9b3361

Ответ 1

Варианты 3 и 4 выходят с самого начала, потому что они просто не работают: 3 срезает объект, 4 создает утечки памяти или недопустимые ссылки.

Из двух других методов я предпочитаю 2: вернуть умный указатель. На самом деле, старайтесь, если это возможно, полностью избегать указателей на raw. К сожалению, С++ делает это много, чтобы писать (и это не тривиальное возражение! Любой, кто когда-либо писал объектно-ориентированный код на С++ и использовал интеллектуальные указатели, разделяет мою боль), но альтернатива еще больнее.

Конечно, есть альтернатива 5: использовать исходные указатели и сборщик мусора.

Ответ 2

Хорошо, мой вкус идет к возвращению умного указателя. здесь является ссылкой на пример Abstract factory, который возвращает интеллектуальный указатель.

my2c

Ответ 3

Я предпочитаю метод 1, потому что он более гибкий. Однако, верните ли вы необработанный указатель или интеллектуальный указатель, это просто вопрос использования объекта. Например, вы можете захотеть вернуть необработанный указатель, потому что знаете, что объект иногда будет использоваться один раз и сразу же будет удален в том же кодовом блоке. В этом случае нет необходимости выполнять накладные расходы на создание объекта интеллектуального указателя. Но если время жизни объекта всегда неопределенно и вас беспокоит утечка памяти, тогда, во что бы то ни стало, используйте метод 2. Методы 3 и 4 неверны.

Ответ 4

Вам нужно управление памятью, нет другого жизнеспособного выбора. Однако вам может не потребоваться управление памятью из метода factory.

Основная проблема с умными указателями - отсутствие ковариации, что является болью при реализации виртуального метода clone. К сожалению, правило ковариации не смягчается в С++ 0x, поэтому остается проблемой.

С другой стороны, возвращая необработанный указатель и оставляя его вызывающему, чтобы его обернуть, открывается дверь к ошибкам (хотя это подход Boost, выбранный для его клонов).

Лично я бы предложил:

  • печально известный auto_ptr или простой указатель, который вызывающий должен обернуть в С++ 03
  • a unique_ptr, как только ваш компилятор получит его

Последние сочетают в себе большинство преимуществ (оставляя ковариацию в стороне) и не содержат незначительных издержек на производительность.

Ответ 5

После того, как вы столкнулись с методом 1, я могу заверить вас, что метод 2, возвращающий boost::shared_ptr или boost::scoped_ptr (обычно первое - это то, что вы хотите, если у вас нет доступа к std::unique_ptr) - это то, что Я искренне рекомендую.