以下代码片段 C++ 的说明

Posted

技术标签:

【中文标题】以下代码片段 C++ 的说明【英文标题】:Explanation for below code snippet C++ 【发布时间】:2013-11-22 17:52:08 【问题描述】:

我正在阅读 C++11 Faq 并遇到了这段代码。我对 C++ 编码有了更好的理解,但我仍然无法理解下面的代码。

    template<class T>
    class Handle 
        T* p;
    public:
        Handle(T* pp) : ppp 
        ~Handle()  delete p;  // user-defined destructor: no implicit copy or move 

        Handle(Handle&& h) :ph.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;

        // ...
    ;
“转让所有权”是什么意思? 为什么复制 ctor 等同于“delete”?它有什么用处?

如果有人可以添加一些带有解释的示例,那将是一个很大的帮助。

【问题讨论】:

What is move semantics?的可能重复 这不是复制 ctor,而是移动 ctor。 观看此视频:channel9.msdn.com/Events/GoingNative/2013/… 【参考方案1】:

它是一个移动构造函数,在 C++11 中引入的特殊 &amp;&amp; 语法采用右值引用,因此对没有名称且不能在代码中的其他任何地方引用的变量的引用。

在构造函数中发生的事情是Handle 取得Handle 的所有权,它通过移动构造函数窃取(将术语传递给我)T* p通过将其值分配给自己的变量,然后将nullptr 设置为传递的右值的变量。

使用它是因为您实际上不需要复制右值,因为该值将不再在代码中使用,因此仅获取其数据是安全的,这避免了可能成本高昂的复制构造函数。

【讨论】:

【参考方案2】:

在 C++ 中,您有复制构造函数和复制操作符,如果您的对象很大,它们会很昂贵。现在在 C++11 中,你有 move 构造函数和 move 运算符,它说“从源头获取所有内容并杀死它”。

mybigthing y ;
...
mybigthing x( move(y)) ;

y 是在内部使用很多东西创建的。在 x(y) 之后,y 现在是空的,所有大的东西都在 x 中。

这样做的主要原因之一是免费从函数返回大对象:

mybigthing f()

  mybigthing tmp ;
  ...
  return tmp ;



  mybigthing y= f() ;

在 c++03 中,这将是可怕的性能。现在它是免费的。编译器需要实际使用 y 作为 f() 的临时内部,并且从不做任何复制。

【讨论】:

【参考方案3】:

转让所有权意味着如果您执行a=b,则b 的内容属于a,并且不再存在于b 中。这在示例A a; dosomething(a); return a; 中更有意义。 a 本地存在于函数中。它的内容被移动到返回值中。如果Astd::string 的typedef,则意味着字符串内部已被移动,而不是制作有意长字符串的副本(可能是html 页面)。但是我相信字符串有一个写时复制标志,所以在这种情况下它不会复制,但其他类可能不会费心实现写时复制。

构造函数和赋值运算符(它们是移动,而不是复制)delete 的原因是因为当前的p 可能指向某个东西。不释放它意味着内存泄漏。

【讨论】:

【参考方案4】:

关于你的第二个问题: 为什么复制ctor等同于“删除”?有什么用?

这是一个答案: http://www.developerfusion.com/article/133063/constructors-in-c11/

C++11 显式删除的构造函数

C++11 还支持显式删除构造函数的概念。 例如,您可以定义一个您不想为其编写的类 任何构造函数,您也不希望编译器生成 默认构造函数。在这种情况下,您需要显式删除 默认构造函数:

类 MyClass 公共: MyClass() = 删除; ;

【讨论】:

以上是关于以下代码片段 C++ 的说明的主要内容,如果未能解决你的问题,请参考以下文章

有趣的 C++ 代码片段,有啥解释吗? [复制]

C++ 代码片段执行

这些 C++ 代码片段有啥作用?

此 Canon SDK C++ 代码片段的等效 C# 代码是啥?

C++ 代码片段(积累)

什么是在 C++ 中获取总内核数量的跨平台代码片段? [复制]