我们说我有一个班级
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
,还是在我的情况下更改了其他任何内容?
答案 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&)
}
的
现在在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