избегать копирования по значению при инициализации ссылки - PullRequest
1 голос
/ 28 апреля 2011

У меня есть интерфейс функции:

struct iFace {
  virtual Type& getType() = 0;
}

и идея состоит в том, чтобы получить его как:

iFace& iface = getIface();
Type& type = iface.getType();

однако я иногда делаю ошибку и пишу:

Type type = iface.getType();

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

Я думал о том, чтобы объявить конструктор копирования, но нигде не определять его, вызывая ошибку времени компоновки, если он используется, но тогда я не смогу использовать конструктор копирования в ЛЮБОЙ ситуации, которая меньше желаемого

Ответы [ 2 ]

8 голосов
/ 28 апреля 2011

Сделайте iFace некопируемым, поместив конструктор копирования и оператор присваивания в "private".Затем предоставьте явный метод копирования.

class Type {
public:
  virtual Copy(Type& dest) = 0;
private:
  Type (const Type &) {assert(false)}
  Type & operator=(const Type &)  {assert(false)}
}

Вы также можете использовать boost noncopyable , чтобы сделать то же самое (реализовано, как описано выше).

Так что если вы хотелиВаш код для копирования, вы бы сделали

Type& type = iface.getType();
Type typeCpy;
type.Copy(typeCpy);

В качестве отступления - я бы добавил, что если вы делаете это из-за проблем с производительностью, вы уверены, что оптимизатор не избавится отвременная копия для вас?

0 голосов
/ 28 апреля 2011

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

struct Class {
    struct Ref {
        Ref(Class& c_) : c(c_) { }
        Class Clone() { return c; }
        // overload -> to provide access to c
      private:
        Class& c;
    };
};

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...