如何知道我是否正在使用复制或移动?

时间:2016-06-07 09:57:40

标签: c++ c++14 move-semantics

我理解C ++ 14标准库使用移动语义吗?换句话说,我可以确信我在以下程序中使用移动而不是副本:

#include <iostream>
#include <string>
#include <vector>

using namespace std::string_literals;

std::vector<std::string> greeting()
{
    std::vector<std::string> vs {"hello"s, "world"s};
    return vs;
}

int main()
{
    std::vector<std::string> s = greeting();
    std::cout << s[0] << " " << s[1] << "\n" ;
}

我有办法检查吗?

在以下示例中如何:

#include <iostream>
#include <string>
#include <vector>

using namespace std::string_literals;

class Greeting {
    public:
    std::string first, second;
    Greeting() { first = "hello"s ; second = "world"s ;};
};

Greeting greetingc()
{
    Greeting g;
    return g;
}

int main()
{
    Greeting g = greetingc();
    std::cout << g.first << " " << g.second << "\n" ;
}

移动还是复制?

1 个答案:

答案 0 :(得分:2)

在大多数情况下,复制和移动之间没有太大区别。只有当你拥有一些你不想复制的东西时才会感兴趣。就像分配给对象的套接字或内存一样。所以只有当某些东西都很昂贵时才会感兴趣(比如当你只需要其中一个时就复制一大块内存)并且你必须要处理所有权(没有两个指针指向相同的内存,或者套接字等等)。 )。

在您的两个示例中,最有可能发生的是编译器将执行RVO返回值优化,从而无需复制或移动。向量定义移动,因此编译器将尽可能使用移动语义(rvalue语义),并且可以使用std :: move强制它。但是你的例子中的更高版本会更快。 Read more about move

如果您感到好奇,可以同时执行复制和移动,并将控制权写入控制台。

Greeting(const Greeting& g)
{
    std::cout << "Copy";
    // Copy it
}

Greeting(Greeting&& g)
{
    std::cout << "Move";
    // Move it
}

通常会发生这种情况。

Greeting foo(){ Greeing a; return a; }
Greeting a; // Normal construction
Greeting b(a); // Copy of 'a'
Greeting c(std::move(a)); // Move, 'a' will be changed
Greeting d(foo()); // Move from rvalue which is returned from foo() unless RVO kicks in