不实现和删除普通运营商有什么区别?

时间:2016-03-27 02:27:02

标签: c++ c++11

我们说我有一个班级

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

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

2 个答案:

答案 0 :(得分: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隐式转换的类型。

答案 1 :(得分:1)

@NicolBolas的anwer是完全可以接受的。这是另一个例子,说明有时不能声明/定义一个函数,因为其他人(例如编译器生成的特殊成员函数)并且您的代码可以调用它(例如通过隐式构造函数或转换运算符)。

UIView
输出#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

现在在C ++ 11之前的版本中,您可以声明但不能定义

void fun(const Wrap &)

Live Example输出链接器错误

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

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

main.cpp:(.text+0x36): undefined reference to 'fun(Base const&)'
输出编译器错误

Live Example(比以前的链接器错误提供更多信息)

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