关于移动构造函数

时间:2013-03-14 04:12:33

标签: c++ move-constructor

我有三个问题:

  1. 在函数f的范围内分配的A :: str的内存。将它移动到全局变量中的元素后,当超出f的范围时,内存块是否仍然安全?

  2. 对于struct B,没有显式给出一个move构造函数,是否有一个像struct A这样的默认构造函数?

  3. struct A
    {
        A(const char* p):str(p){}
        A(const A&& a) : str(std::move(a.str))
        {
        }
    
        string str;
    };
    
    struct B
    {
        B(const char* p):str(p){}
    
        string str;
    };
    
    vector<A>vec;
    
    void f()
    {
        vec.emplace_back(A("hello")); //in vc2010 it will invoke emplace_back(T&&)
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        f();
        const char* p = vec[0].str.c_str();
        cout << p << endl;
        return 0;
    }
    

    3.我可以确认STL容器中从未发生过这种危险情况吗?

    struct String
    {
        char* pStr; //allocate on heap
        int* someptr; //if point to allocate on stack 
        size_t len;
    
        String (const String&& s)
        {
        //  something like this:
            pStr = s.pStr;  //ok,safe
            len = s.len; 
            s.pStr = nullptr;
    
            someptr = s.someptr; //danger
        }
    };
    

2 个答案:

答案 0 :(得分:1)

  1. 这是安全的,因为为临时A对象分配的内存被“移动”到向量元素中。

  2. 在VC ++ 2010中,没有自动生成移动构造函数,但VC ++ 2010在C ++ 11标准完成之前发布,并且移动构造函数/赋值运算符的规则有所改变。我不确定VC ++ 2012是否会生成它们,但无论哪种方式都是安全的(唯一的区别是它可能被复制或移动)。

答案 1 :(得分:0)

  1. A::str在内部分配的任何内存都由它控制,并且不会受到创建A时有效范围的任何影响。所以你的代码非常安全。

  2. 当既未定义复制构造函数也未定义移动构造函数(也不定义复制/移动赋值运算符)时,编译器将为您生成它们。因此B有一个默认生成的移动构造函数与A的构造函数相同。