我正在阅读C++11 Faq并遇到此代码。我对C ++编码有了更好的理解,但我仍然无法理解下面的代码。
template<class T>
class Handle {
T* p;
public:
Handle(T* pp) : p{pp} {}
~Handle() { delete p; } // user-defined destructor: no implicit copy or move
Handle(Handle&& h) :p{h.p} { h.p=nullptr; }; // transfer ownership
Handle& operator=(Handle&& h) { delete p; p=h.p; h.p=nullptr; return *this; } // transfer ownership
Handle(const Handle&) = delete; // no copy
Handle& operator=(const Handle&) = delete;
// ...
};
delete
”?它是如何有用的?如果有人可以添加一些解释的例子,那将是一个很大的帮助。
答案 0 :(得分:1)
它是一个移动构造函数,C ++ 11中引入的特殊&&
语法采用右值引用,因此引用了一个没有名称且不能在代码中的任何其他地方引用的变量。< / p>
构造函数中发生的事情是Handle
以窃取的方式获取通过移动构造函数传递的Handle
的所有权(传递给我这个术语) T* p
通过将其值分配给自己的变量,然后将nullptr
设置为传递的右值变量。
使用它是因为你不需要复制rvalue,因为代码中不再使用该值,因此只需获取其数据是安全的,这可以避免可能代价高昂的复制构造函数。
答案 1 :(得分:0)
在C ++中,你有复制构造函数和复制操作符,如果你的对象很大,这些操作符很昂贵。现在在C ++ 11中你有移动构造函数和移动运算符,它说“从源头获取所有内容并将其删除”。
mybigthing y ;
...
mybigthing x( move(y)) ;
y内部有很多东西。在x(y)之后,y现在为空,所有大的东西都在x中。
其中一个主要原因是从函数中返回大对象:
mybigthing f()
{
mybigthing tmp ;
...
return tmp ;
}
{
mybigthing y= f() ;
}
在c ++ 03中,这将是非常糟糕的表现。现在它是免费的。编译器需要实际使用y作为f()
的临时内部,并且永远不会做任何副本。
答案 2 :(得分:0)
转让所有权意味着如果您a=b
b
的内容属于a
且b
中不再存在,则{A a; dosomething(a); return a;}
。这在示例a
中更有意义。 A
在函数中本地存在。它的内容被移入返回值。如果std::string
是delete
的typedef,则意味着已移动字符串内部,而不是制作故意长字符串的副本(可能是html页面)。但是我相信字符串在写标志上有一个副本,所以它不会在那种情况下复制,但其他类可能不会在写入时实现副本。
构造函数和赋值运算符(移动而不是复制)p
的原因是因为当前{{1}}可能指向某个东西。不释放它意味着内存泄漏。
答案 3 :(得分:0)
关于你的第二个问题: 为什么复制文件等同于“删除”?它有用吗?
这是一个答案: http://www.developerfusion.com/article/133063/constructors-in-c11/
C ++ 11显式删除的构造函数
C ++ 11还支持显式删除构造函数的概念。 例如,您可以定义一个您不想编写的类 任何构造函数,你也不希望编译器生成 默认构造函数。在这种情况下,您需要明确删除 默认构造函数:
class MyClass {public: MyClass()=删除; };