在初始化引用时避免按值复制

avoid copy by value when initializing reference

本文关键字:复制 初始化 引用      更新时间:2023-10-16

我有一个函数接口:

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

的想法是像这样检索它:

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

然而,我偶尔会犯一个错误,写:

Type type = iface.getType();

按值复制,这是我想要避免的。然而,当我犯这样的错误时,编译器不会发出警告,因为它的合法语法。我想为此触发编译时错误,问题我的替代方案是什么?

我想过声明一个复制构造函数,但没有在任何地方定义它,如果使用它会导致链接时间错误,但然后我将无法在任何情况下使用复制构造函数,这是不理想的

通过将复制构造函数和赋值操作符置于"private"下,使iFace不可复制。然后提供一个显式Copy方法。

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);

作为题外话——我想补充一下,如果您这样做是出于性能考虑,您确定优化器不会为您清除临时副本吗?

在这里返回一个指针似乎是合理的,但是如果您担心混淆所有权,您可以返回引用的包装器。

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

原始类可以正常复制,但引用必须显式执行。我对这个想法并不热衷(比起那些不知道复制语义如何工作的用户,我更倾向于那些不小心长时间使用复制语义的用户),但理论上这是可行的。

相关文章: