值类型(现代C++)

默认情况下选件 C++ 类是值类型。 本主题提供值类型表示概述和问题与其使用相关。

值用于. 引用类型

默认情况下,如 C++ 选件类是值类型。 他们可以指定引用类型,使得多态行为支持面向对象的编程方法。 值类型从内存的角度有时会看到,并且窗体控件,而引用类型是有关基类和虚函数多态目的。 默认情况下,值类型 copyable,这意味着始终具有复制构造函数和复制赋值运算符。 对于引用类型,可使选件类非 copyable (请禁用复制构造函数和复制赋值运算符) 并使用虚拟析构函数,支持其既定多态性。 值类型也是有关目录,那么,当将其复制时,始终提供了两个独立的值可以单独修改。 引用类型是有关标识–它是哪种类型的对象? 因此,“引用类型”也称为“多态类型”。

如果事实需要一个类似于引用的类型 (基类,虚函数),如下面的代码中,的 MyRefType 选件类所示需要显式禁用复制。

// cl /EHsc /nologo /W4

class MyRefType {
private:
    MyRefType & operator=(const MyRefType &);
    MyRefType(const MyRefType &);
public:
    MyRefType () {}
};

int main()
{
    MyRefType Data1, Data2;
    // ...
    Data1 = Data2;
}

编译上面的代码产生以下错误:

  
  
  

值类型和移动性能

复制赋值开销避免使用的是由于新副本优化。 例如,那么,当您插入到字符串元矢量的一个字符串,则会变为上不进行复制的重新分配,因此,只有移动,即使它导致该矢量的增大。 这同样适用于其他操作,例如对两个非常大的对象的添加操作。 如何使这些值操作优化? 在某些 C++ 编译器,编译器将隐式启用此您的,这与复制构造函数可由编译器自动生成。 但是,在 Visual C++ 中,您的选件类需要“选择”中通过声明移动分配和构造函数在类定义中。 这种状态的使用二进制文件" and "符 (&& %) rvalue 引用在适当的成员函数声明和定义移动构造函数并移动分配方法。 您还需要正确的代码“窃取胆量”error 源对象插入。

如何决定是否需要启用的移动? 如果已经知道需要启用的复制构造,您可能希望启用的移动,如果它比一个多层次复制可以节省。 但是,因此,如果您知道需要将支持,它不一定表示要启用的副本。 此后用例称为“移动类型”。 一个示例已经在标准库中为 unique_ptr。 作为旁注,旧 auto_ptr 已弃用并将其 unique_ptr 替换精确因不移动语义支持在 C++ 的早期版本。

使用移动语义可以返回值或插入到元。 移动是复制的优化。 对堆分配的需要作为工作区域。 考虑以下伪代码:

#include <set>
#include <vector>
#include <string>
using namespace std;

//...
set<widget> LoadHugeData() {
    set<widget> ret;
    // ... load data from disk and populate ret
    return ret;
}
//...
widgets = LoadHugeData();   // efficient, no deep copy

vector<string> v = IfIHadAMillionStrings();
v.insert( begin(v)+v.size()/2, "scott" );   // efficient, no deep copy-shuffle
v.insert( begin(v)+v.size()/2, "Andrei" );  // (just 1M ptr/len assignments)
//...
HugeMatrix operator+(const HugeMatrix& , const HugeMatrix& );
HugeMatrix operator+(const HugeMatrix& ,       HugeMatrix&&);
HugeMatrix operator+(      HugeMatrix&&, const HugeMatrix& );
HugeMatrix operator+(      HugeMatrix&&,       HugeMatrix&&);
//...
hm5 = hm1+hm2+hm3+hm4+hm5;   // efficient, no extra copies

Hh438479.collapse_all(zh-cn,VS.110).gif启用相应的值类型的移动

对于移动超过一个多层次复制可以节省相当于值的选件类,启用移动构造和移动分配有效的。 考虑以下伪代码:

#include <memory>
#include <stdexcept>
using namespace std;
// ...
class my_class {
    unique_ptr<BigHugeData> data;
public:
    my_class( my_class&& other )   // move construction
        : data( move( other.data ) ) { }
    my_class& operator=( my_class&& other )   // move assignment
    { data = move( other.data ); return *this; }
    // ...
    void method() {   // check (if appropriate)
        if( !data ) 
            throw std::runtime_error("RUNTIME ERROR: Insufficient resources!");
    }
};

如果启用复制构造/分配,还可实现移动构造/分配,则超过一个多层次复制可以节省。

这些 非值 类型是移动,例如,当无法克隆资源时,因此,只有所有权转移。 示例:unique_ptr。

内容

请参见

概念

C++类型系统(现代C++)

其他资源

返回C++ (现代C++)的欢迎

C++语言参考

标准C++库参考