2016-08-01 3 views
5

У меня есть класс А, который имеет переменные-члены типов M и N. времена жизни этих объектов, как предполагается, должны быть ограничены временем жизни А.Интеллектуальные указатели против значения в качестве переменных членов

Я рассматриваю

class A { 
    M member1; 
    N member2; 
} 

против

class A { 
    std::unique_ptr<M> member1; 
    std::unique_ptr<N> member2; 
} 

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

+5

Если нет причин указывать указатель, у кого есть указатель? Все участники «уничтожены» в деструкторе. – NathanOliver

+0

Единственный раз, когда вы * могли бы хотеть создавать «M» и «N» в качестве указателей, было бы там, где они очень большие, а их создание в стеке может привести к выходу из пространства стека. –

+2

Используйте только динамическое распределение, если вы есть причина и веская причина. Например, если ваши объекты-члены являются гигантскими и могут разбивать стек. В противном случае не бессмысленно вводить накладные расходы на динамическое распределение/косвенность. –

ответ

2

Это зависит от размеров N и M и как вы планируете использовать class A.

  1. Если типы N и M невелики, т.е. одного машинного слова, то иметь дополнительные накладные расходы на создание и поддержание указателей является пустой тратой времени и пространстве.
  2. Если типы N и M очень большие, и вы планируете объявить объект class A на стек, тогда было бы лучше использовать указатели. В этом случае большие объекты типов N и M будут выделены в области кучи (и, скорее всего, это позволит вам отладить очень неприятные проблемы с переполнением стека).
  3. Если, с другой стороны, вы планируете динамически выделять объект class A, то наличие переменных-членов достаточно, потому что в этом случае все будет выделено в области кучи, и вы также сохраните накладные расходы.

Надеюсь, что это ясно.

4

использование станд :: unique_ptr если

  1. M и N являются базовые классы полиморфных иерархиях
  2. member1 и member2 являются обязательными членами, которые могут быть nullptr
  3. M и N достаточно велики, что не может быть выделяется на стеке программы
+0

И это ** все ** _rules большого пальца и появление? –

3

Yep, как правильно, но ...

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

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

  1. Возможно, вы захотите изменить значения member1 или member2 на протяжении всего жизненного цикла объекта A. Метод интеллектуальных указателей может сделать это дешевой операцией, если объекты M и N велики.
  2. Возможно, вы захотите воспользоваться полиморфизмом.Если M или N был базовым классом, реализация на основе указателей имела бы гибкость в использовании подклассов M или N.
  3. Реализация на основе указателя могла позволить вам отложить выделение члена1 или члена2 до более позднего, более подходящего, время в жизненном цикле A.
Смежные вопросы