【问题标题】:About move constructor关于移动构造函数
【发布时间】:2013-03-14 04:12:32
【问题描述】:

我有三个问题:

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

  2. 对于 struct B,没有明确给出移动构造函数,是否有像 struct 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.我能否确认这种危险情况在 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
    }
};

【问题讨论】:

    标签: c++ move-constructor


    【解决方案1】:
    1. 这是安全的,因为分配给临时 A 对象的内存被“移动”到了向量元素中。

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

    【讨论】:

      【解决方案2】:
      1. A::str 内部分配的任何内存都由它控制,并且不受创建 A 时有效范围的任何影响。所以你的代码是绝对安全的。

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

      【讨论】:

        猜你喜欢
        • 2014-11-08
        • 2011-05-22
        • 1970-01-01
        • 1970-01-01
        • 2017-11-03
        • 1970-01-01
        • 2021-11-15
        • 2020-03-22
        相关资源
        最近更新 更多