【问题标题】:c++11: how to understand the function movec++11:如何理解函数move
【发布时间】:2016-06-30 09:10:06
【问题描述】:

我看不懂c++11中的函数move。

来自here,我得到了以下信息:

虽然请注意 - 在标准库中 - 移动意味着 移出对象处于有效但未指定的状态。哪一个 意味着,在这样的操作之后,移动的值 对象应该只被销毁或分配一个新值;访问它 否则会产生一个未指定的值。

在我看来,在 move() 之后,被移动的对象已经“清除”了。但是,我在下面做了一个测试:

std::string str = "abcd";
std::move(str);
std::cout<<str;

我的屏幕上出现了abcd
那么str 被销毁了吗?如果是这样,我可以得到abcd,因为我很幸运?还是我误解了函数move

另外,当我阅读C++ Primer时,我得到了这样一个代码:

class Base{/* ... */};
class D: public Base{
public:
    D(D&& d): Base(std::move(d)){/* use d to initialize the members of D */}
};

我现在很困惑。如果函数move会清空对象,参数d会清空,怎么能“用d初始化D的成员”呢?

【问题讨论】:

  • 你很幸运。或者倒霉,这取决于你的观点。

标签: c++11 move


【解决方案1】:

std::move 实际上并没有任何事情。它大致类似于强制转换表达式,因为返回值是原始对象,但处理方式不同。

更准确地说,std::move 以一种形式返回对象,该形式允许其资源被“窃取”以用于其他目的。原始对象或多或少仍然有效(您只应该对它做某些特殊的事情,尽管这主要是一个约定问题,不一定适用于非标准库对象),但被盗的资源没有不再属于它,一般不会再被它引用。

但是! std::move 本身不会偷窃。它只是为允许偷窃做准备。由于您没有对结果做任何事情,更不用说可以利用机会的事情了,所以什么都不会被盗。

【讨论】:

    【解决方案2】:

    std::move 不会移动任何东西。 std::move 只是一个执行强制转换的函数模板。 std::move 无条件地将其参数转换为右值,

    std::move(str);
    

    使用这个表达式,你只是在做从左值到右值的类型转换。

    对程序进行小修改以便更好地理解。

     std::string str = "abcd";
     std::string str1 = std::move(str);
     std::cout<<str<<std::endl;
     std::cout<<str1<<std::endl; 
    

    str lvalue typecast to rvalue by std::move, std::string = std::move(str); =>这个表达式调用string move constructor,在这个地方实际窃取资源。 str resources(abcd) 被钢化并打印空字符串。

    这里是 move 函数的示例实现。请注意,它不是标准库的完整实现。

    template<typename T> // C++14; still in
    decltype(auto) move(T&& param) // namespace std
    {
    using ReturnType = remove_reference_t<T>&&;
    return static_cast<ReturnType>(param);
    }
    

    将 std::move 应用于一个对象会告诉编译器该对象有资格被移出。它转换为右值。

    class Base{/* ... */};
    class D: public Base{
    public:
        D(D&& d): Base(std::move(d)){/* use d to initialize the members of D */}
    };
    

    Base(std::move(d)) 它只会向上转换,只移动基类部分。

    这里还有一件有趣的事情要为您学习。如果您不使用std::moveD(D&amp;&amp; d): Base(d) 那样调用基类析构函数,则 d 将被视为所涉及的基类的左值和复制构造函数,而不是移动构造函数。更多详情请参考Move constructor on derived object

    【讨论】:

      猜你喜欢
      • 2012-11-17
      • 2014-09-30
      • 2023-03-22
      • 2015-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-15
      相关资源
      最近更新 更多