在初始化引用时避免按值复制
avoid copy by value when initializing reference
我有一个函数接口:
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;
};
};
原始类可以正常复制,但引用必须显式执行。我对这个想法并不热衷(比起那些不知道复制语义如何工作的用户,我更倾向于那些不小心长时间使用复制语义的用户),但理论上这是可行的。
相关文章:
- 不能将复制初始化与隐式转换的多个步骤一起使用
- 在引用初始化中使用已删除的复制构造函数进行复制初始化
- 为什么 std::string s = "123" 当不涉及副本时被视为复制初始化?
- 复制初始化:为什么即使关闭了复制省略,也没有调用move或copy构造函数
- 复制初始化与直接初始化已更改
- 为什么在直接初始化和赋值中传递 lambda 而不是在复制初始化中传递 lambda 时会编译?
- 复制初始化 - 从 'int' 类型转换为非标量类型
- 我可以制作一个对象方法,如果单独调用,它将自行修改,但如果在复制初始化期间调用,则会返回一个新对象?
- 如果值来自成员变量,则复制初始化和参考初始化之间的C 差异
- 复制初始化表单 '= {}'
- 对C++所做的更改使复制初始化适用于具有显式构造函数的类
- 显式强制转换、直接初始化和复制初始化之间的行为不同
- 是直接初始化还是复制初始化
- 为什么复制初始化是这样的?为什么需要复制构造函数
- 在复制初始化中,对复制构造函数的调用是显式的还是隐式的
- 复制列表初始化和传统复制初始化之间的任何区别
- 复制初始化和显式构造函数-编译器的差异
- 如何为显式重载构造函数启用复制初始化
- POD变量的直接初始化不起作用,但当将变量推到向量上时,复制初始化起作用
- 为什么类构造函数在通过复制初始化对象时不起作用