2016-03-27 45 views
9

比方说,我有一个类不执行和删除常用操作符有什么区别?

class Object 
{ 
public: 
    Object(int i) : num(i) {}; 

    int getNum() const { return num; } 
private: 
    int num; 
}; 

现在,如果我尝试这样做

Object obj{ 1 }; 
Object obj2{ 2 }; 
Object obj3 = obj + obj2; //This is wrong 

这是非法的:'Object' does not define this operator or a conversion to a type acceptable to the predefined operator

添加Object operator+(const Object&) = delete;不会改变任何内容,除了错误消息:'Object Object::operator +(const Object &)': attempting to reference a deleted function

deletedelete是否只有具有隐式声明(如赋值运算符和复制/移动构造函数)的运算符才需要,还是它改变了我的情况?

+0

我认为这是添加到语言的主要原因是防止复制或明确朝。 – karakfa

+0

这就是我的想法,但如果允许的话,就必须有一个原因。 – Rakete1111

回答

8

是否只需要具有隐式声明(如赋值运算符和复制/移动构造函数)的运算符的删除操作,还是在我的情况下更改其他任何内容?

否和否。你的情况对于任何这种差异都很重要。

= delete有两个目的:

1:它强制消除功能这将(可能)否则在那里。即特殊成员功能。

2:它指定具有该签名的函数不能被调用。这实质上是#1的泛化。

后者的原型示例用于防止函数参数的隐式转换。如果你这样做:

void foo(float val); 
void foo(int) = delete; 

你不能再叫foo(5);您必须使用foo(5.f)。为什么?因为编译器会看到第二个重载,请查看它与最佳的调用匹配,然后立即失败,因为该函数被删除。

这有时这样做还有:

void foo(float val); 
template<typename T> void foo(T&&) = delete; 

这确保您可以与实际float调用它。没有可以从float转换的类型。

+0

为什么在最后一种情况下模板需要右值引用?在我看来,只是一个普通的“模板 void foo(T)= delete”就足够了。 –

+0

@SamVarshavchik:可能没有必要。 –

+0

@SamVarshavchik考虑,例如'void g(AbstractClassWithConversionToFloat&x){foo(x); }'。 'void foo(T)= delete;'会产生替换失败(因为函数参数类型不能是抽象的)并且不正确地阻止了调用。 –

1

@NicolBolas的anwer是完全可以接受的。这里有另一个例子来说明,有时候不能不声明/定义一个函数,因为别人会这样做(比如编译器生成特殊的成员函数),而你的代码可以调用它(例如通过隐含的构造函数或转换运算符)。

#include <iostream> 

// your code 
struct Base {}; 

// some teammate 
struct Wrap 
{ 
    /* implicit */ Wrap(Base const& b) {} 
}; 

void fun(Wrap const&) { std::cout << __PRETTY_FUNCTION__ << '\n'; } 

// client code 
int main() 
{ 
    Base b; 
    fun(b); // oops, probably didn't intend to call fun(Wrap const&) 
} 

Live Example输出void fun(const Wrap &)

现在昔日预C++ 11,你可以声明,但没有定义

void fun(Base const&); // no definition provided 

Live Example输出的链接错误

从C++ 11开始,您可以明确删除相同的功能

void fun(Base const&) = delete; // C++11 onwards 

Live Example输出的编译器错误(比以前的链接错误更翔实)

main.cpp:20:5: error: call to deleted function 'fun' 
    fun(b); // oops, probably didn't intend to call fun(Wrap const&) 
    ^~~ 
main.cpp:6:6: note: candidate function has been explicitly deleted 
void fun(Base const&) = delete; // C++11 onwards 
    ^
相关问题