2011-04-27 99 views
1

我有一个函数接口:避免拷贝初始化时参考

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

和想法是检索它喜欢:

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

然而,我偶尔我做了错误,并写上:

Type type = iface.getType(); 

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

我想过声明拷贝构造函数,但没有在任何地方定义它,如果它的使用造成的链接时错误,但后来我将无法使用拷贝构造函数任何情况,小于desiderable

+0

你无法真正拥有它。 – 2011-04-27 21:18:47

+0

这就是我所害怕的,所以我想在这里要求确认。感谢您的确认 – lurscher 2011-04-27 21:20:02

+0

这取决于类型是什么。如果你可以使类型抽象,那么你将无法创建一个实例。 – 2011-04-27 22:09:40

回答

8

通过将复制构造函数和赋值运算符置于“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); 

顺便说一句 - 我想补充一点,如果你这样做是因为性能问题,你一定优化器没有按为你摆脱临时副本?

+0

这属于复制构造函数变得不太可用的情况。让我们保持这个计划“如果一切都失败” – lurscher 2011-04-27 21:18:26

+0

@lurscher,你也可以提供一个明确的副本,看看我的编辑。 – 2011-04-27 21:19:47

+0

我们可以使用显式关键字来限制复制构造函数吗? – lurscher 2011-04-27 21:21:32

-1

在这里返回一个指针似乎是合理的,但如果让所有权感到困惑,您可以返回一个包含引用的包装。

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

原始类可以正常复制,但必须明确地做引用。我对这个想法并不满意(我认为应该少一个用户不认识复制语义如何工作的人,而不是那些意外地持有这些太长时间的人),但理论上这是可行的。