Как действительно используют станд.:: auto_ptr в классе необходимо ли скопировать конструкцию?

В родительской таблице попробуйте установку

border-collapse:separate; 
border-spacing:5em;

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

8
задан J-16 SDiZ 17 July 2009 в 04:08
поделиться

9 ответов

Вы можете попробовать следующий код:

    foo(const foo& rhs)
        :   _a(rhs._a)
        ,   _b(rhs._b)
        ,   _c(_rhs._c.get() ? new bar(*_rhs._c.get()) : 0)
    {
    }

(Оператор присваивания аналогичен.)

Однако это будет работать, только если bar будет CopyConstructible и если это действительно делает что хотите. Дело в том, что оба объекта foo ( _rhs и сконструированный) будут иметь разные указатели в _c .

Если вы хотите, чтобы они разделяли указатель, тогда вы не должны использовать auto_ptr , поскольку он не поддерживает совместное владение. Рассмотрим в таком случае использование shared_ptr из Boost.SmartPtr , например (который будет включен в новый стандарт C ++). Или любая другая реализация общего указателя, поскольку это настолько распространенная концепция, что доступно множество реализаций.

16
ответ дан 3 November 2019 в 14:03
поделиться

Как вы обнаружили, вы не можете скопировать std :: auto_ptr таким образом. Кто владеет указанным объектом после копии? Вместо этого вы должны использовать умный указатель с подсчетом ссылок. В библиотеке Boost есть shared_ptr , который вы можете использовать.

8
ответ дан 3 November 2019 в 14:03
поделиться

Во-первых, я бы избегал auto_ptr

Передача права собственности хороша в некоторых сценариях, но я считаю, что они редки, и теперь легко доступны «полноценные» библиотеки интеллектуальных указателей. (IIRC auto_ptr был компромиссом для включения хотя бы одного примера в стандартную библиотеку без задержек, которые потребовались бы для хорошей реализации.)

См., Например, здесь
или здесь

Определите семантику
] Должна ли копия foo содержать ссылку на тот же экземпляр bar? В этом случае используйте boost :: shared_ptr или ( boost :: intrusive_ptr ) или аналогичную библиотеку.

Или нужно создать глубокую копию? (Иногда это может потребоваться, например, при наличии состояния с задержкой). Я не знаю какой-либо стандартной реализации этой концепции, но создать ее аналогично существующим интеллектуальным указателям несложно.

   // roughly, incomplete, probably broken:
   template <typename T>
   class deep_copy_ptr
   {
      T * p;
     public:
      deep_copy_ptr()  : p(0) {}
      deep_copy_ptr(T * p_)  : p(p_) {}
      deep_copy_ptr(deep_copy_ptr<T> const & rhs)  
      {
        p = rhs.p ? new T(*rhs.p) : 0;
      }
      deep_copy_ptr<T> & operator=(deep_copy_ptr<T> const & rhs)
      {
         if (p != rhs.p)
         {
           deep_copy_ptr<T> copy(rhs);
           swap(copy);
         }
      }
      // ...
   }
3
ответ дан 3 November 2019 в 14:03
поделиться

std :: auto_ptr - хороший инструмент для управления динамическими объектами в C ++, но для того, чтобы использовать его эффективно, важно понимать, как работает auto_ptr. В этой статье объясняется, почему, когда и где следует использовать этот интеллектуальный указатель.

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

Если его нужно клонировать, убедитесь, что у него есть конструктор копирования, а затем создайте новый auto_ptr, который содержит копию вашего объекта, см. Ответ Адама Бадура .

Если нужно shared, вы должны использовать boost :: shared_ptr , как предложил Martin Liversage .

1
ответ дан 3 November 2019 в 14:03
поделиться

Мой первый выбор - вообще избегать auto_ptr в этой ситуации. Но если бы я был прижат к стене, я мог бы попытаться использовать ключевое слово mutable в объявлении _c - это позволит изменить его даже из константной ссылки.

0
ответ дан 3 November 2019 в 14:03
поделиться

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

В этом случае, тогда вы ' Я захочу, чтобы ваш конструктор копирования и оператор присваивания принимали неконстантные ссылки на свои аргументы и выполняли там инициализацию / присвоение.

0
ответ дан 3 November 2019 в 14:03
поделиться

Вся идея auto_ptr состоит в том, что есть только один владелец упомянутого объекта. Это означает, что вы не можете скопировать указатель, не удалив первоначального владельца.

Поскольку вы не можете скопировать его, вы также не можете скопировать объект , содержащий и auto_ptr .

Вы можете попробовать использовать семантику перемещения, например, используя std :: swap вместо copy.

0
ответ дан 3 November 2019 в 14:03
поделиться

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

Затем в конструкторе копирования я инициализирую auto_ptr как clone () другого; например,

class Foo
{
   public:
      Foo(const Foo& rhs) : m_ptr(rhs.m_ptr->clone());
   private:
      std::auto_ptr<T> m_ptr;
};

clone () обычно реализуется следующим образом:

class T
{
   std::auto_ptr<T> clone() const
   {
      return std::auto_ptr<T>(new T(*this));
   }
};

Мы налагаем условие, что T является клонируемым, но это условие, по существу, налагается наличием копируемого класса с членом auto_ptr.

1
ответ дан 3 November 2019 в 14:03
поделиться

Вы не можете использовать константные ссылки в конструкторе копирования или операторе присваивания, который включает auto_ptr <> . Удалите константу. Другими словами, используйте объявления типа

foo(foo & rhs);
foo & operator=(foo & rhs);

. Эти формы явно упоминаются в Стандарте, в первую очередь в разделе 12.8. Их следует использовать в любой соответствующей стандарту реализации. Фактически, параграфы 5 и 10 из 12.8 говорят, что неявно определенный конструктор копирования и оператор присваивания (соответственно) будет принимать неконстантную ссылку, если это требуется любому из членов.

-1
ответ дан 3 November 2019 в 14:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: