2013-03-14 95 views
1

我有三个问题:在函数f的范围分配关于移动构造函数

  1. A ::海峡的记忆。将它移动到全局var vec中的元素后,当f的范围超出时,内存块是否仍然安全?

  2. 对于结构B,没有明确给出移动构造函数,是否有像结构A那样的默认构造函数?

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.And我可以证实这种危险情况,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 
    } 
}; 

回答

1
  1. 它是安全的,因为分配给临时变量的对象的内存是“移动”到向量元素。

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

0
  1. 通过A::str内部分配的任何内存是由它控制和由什么范围实际上是在创建A当任何方式不会受到影响。所以你的代码是完全安全的。

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