2013-03-14 97 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的一樣。