C ++ Не копируется, кроме иногда - PullRequest
7 голосов
/ 07 июля 2011

Я считаю, что создание класса, не подлежащего копированию, очень помогает мне в качестве кода.Первоначально я делал это с boost :: noncopyable, но обнаружил, что ошибки компилятора VC ++ не так полезны, как с закрытыми членами (двойной щелчок приводит к неправильному месту в коде).

T(T const&);
T& operator=(T const&);

Действительно,это предупредило меня о довольно многих случаях, когда занятия не были переданы в качестве ссылки, где они должны иметь.Настолько, что я бы очень хотел получить предупреждение даже о классах, что мне просто нужно скопировать конструкцию один раз.

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

Или, может быть, существует более эффективный способ для всех вместе?

Ответы [ 4 ]

6 голосов
/ 07 июля 2011

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

Возможно, вы захотите сохранить приватность оператора присваивания, возможно, для этого будет полезна база NonAssignable.

2 голосов
/ 07 июля 2011

Я думаю, вы сами назвали идеальный путь.

Я только что вспомнил небольшой (?) Маленький трюк, который я однажды играл в другой кодовой базе, над которой я работал:

struct T
{
    friend class SomeClientThatCanConstructT;
    T(T const&);

  private:
     T(T const&);           
};

Как обсуждалось в комментариях, следующее не будет работать

Вы можете выбрать явное имя (например, CopyConstruct) и полагаться на одинаковую эффективность RVO:

struct T
{
     inline T CopyConstruct() const     { return *this; }
     inline T& AssignTo(T& dst) const   { return dst = *this; }
     inline T& AssignFrom(const T& src) { return *this = src; }

  private:
     T(T const&);
     T& operator=(T const&);
};

0 голосов
/ 08 июля 2011

Мне не нравится идея ограничения типа (CopyConstructible является широко используемой концепцией в stdlib), потому что она может быть использована неправильно.Если вы можете создать объект из другого экземпляра, он должен быть копируемым.Это также отвлекает читателя от важного кода без какой-либо реальной цели.

Может быть, предупреждение или утверждение в режиме отладки, которое вызывается конструктором копирования, действительно то, что вы ищете?

0 голосов
/ 07 июля 2011

Вы можете по умолчанию создать T, а затем добавить метод assign для использования.Тем не менее, это не совсем оптимально, указывая на то, что вы, возможно, захотите пересмотреть свои потребности в копировании.

...