C++ 是移动构造函数';始终';比复制构造函数更高效?

C++ 是移动构造函数';始终';比复制构造函数更高效?,c++,C++,我一直在研究移动构造函数与复制构造函数的比较。从我读到的stackoverflow和其他信息来源来看,更多的是关于如何“调用”它们的,但是我没有找到一个明确的答案,关于它们是否“总是”比复制构造函数更有效,也许我只是在搜索错误的东西 无论如何,我问这个问题的原因是因为以下场景将使Move构造函数比Copy构造函数更高效: class Test { std::string *name; std::vector<std::string> *friends; publi

我一直在研究移动构造函数与复制构造函数的比较。从我读到的stackoverflow和其他信息来源来看,更多的是关于如何“调用”它们的,但是我没有找到一个明确的答案,关于它们是否“总是”比复制构造函数更有效,也许我只是在搜索错误的东西

无论如何,我问这个问题的原因是因为以下场景将使Move构造函数比Copy构造函数更高效:

class Test {

    std::string *name;
    std::vector<std::string> *friends;

public:
    Test() : name{nullptr}, friends{nullptr} {} // If not initialized they may be pointing to random memory
    Test(std::string name, std::vector<std::string> friends) : name{nullptr}, friends{nullptr} {
        this->name = new std::string{std::move(name)}; // Is the std::move necessary, or is 'name' still considered an r-value even though it has a variable name now (if it had been passed as an r-value to the constructor in the first place)
        this->friends = new std::vector<std::string>{std::move(friends)}; // Is the std::move necessary, or is 'friends' still considered an r-value even though it has now got a variable name (if it had been passed as an r-value to the constructor in the first place)
    }
    
    // Copy constructor
    Test(const Test &source) : name{nullptr}, friends{nullptr} {
        name = new std::string{*source.name};
        friends = new std::vector<std::string>{*source.friends};
    }

    // Move constructor
    Test(Test &&source) noexcept : name{source.name}, friends{source.friends} {
        source.name = nullptr;
        source.friends = nullptr;
    }

    // Destructor
    ~Test() {
        delete name;
        delete friends;
    }

};
类测试{
std::string*名称;
向量*朋友;
公众:
Test():name{nullptr},friends{nullptr}{}//如果没有初始化,它们可能指向随机内存
Test(std::string name,std::vector friends):name{nullptr},friends{nullptr}{
this->name=new std::string{std::move(name)};//std::move是否必要,或者“name”是否仍然被视为一个r值,即使它现在有一个变量名(如果它首先作为r值传递给构造函数的话)
this->friends=new std::vector{std::move(friends)};//std::move是否必要,或者“friends”是否仍然被视为一个r值,即使它现在已经获得了一个变量名(如果它首先作为r值传递给构造函数的话)
}
//复制构造函数
Test(consttest&source):name{nullptr},friends{nullptr}{
name=newstd::string{*source.name};
friends=new std::vector{*source.friends};
}
//移动构造函数
Test(Test&&source)noexcept:name{source.name},friends{source.friends}{
source.name=nullptr;
source.friends=nullptr;
}
//析构函数
~Test(){
删除姓名;
删除好友;
}
};
从头到尾,或者事实上,在我的帖子中的任何地方,如果我陈述错误,请纠正我。

从我的理解来看,移动构造函数肯定会更有效率,特别是当向量和字符串的大小变得更大时,因为我们复制的是内存地址,而不是按值复制对象。如果我能从代码中留下的关于std::move的两条评论/问题中得到反馈,那将是非常有帮助的。如果在这种情况下有必要或没有必要,我会在两条类似的评论/问题中解释我的思考过程

这就是我的问题所在。。。因为当我没有任何指向任何东西的属性/成员变量时,我不确定,或者事实上我更宽容地认为移动构造函数不会比复制构造函数快,但我需要一些帮助来确认这一点

下面是一个类似的类,但已重构为代码,其中包含了属性/成员变量:

class Test {

    std::string name;
    std::vector<std::string> friends;

public:
    Test() : name{}, friends{} {} // 'name' is initialzied to "" and 'friends' I am not quite sure what it is initialized to, maybe just an empty vector, but I'm not sure
    Test(std::string name, std::vector<std::string> friends) : name{name}, friends{friends} {} // No need for any code inside the code block --- is that what it's called? Or just code brackets? Or what? lol

    // Copy constructor
    Test(const Test &source) : name{source.name}, friends{source.friends} {} // Again, no need for any extra code in the -- whatever it's called --

    // Move constructor
    Test(Test &&source) noexcept : name{source.name}, friends{source.friends} {}

    // Destructor
    ~Test() {} // No need to define one our selves but I just left it like this anyways, just removed the 'delete' statements

};
类测试{
std::字符串名;
病媒朋友;
公众:
Test():name{},friends{}/'name'被初始化为“”,而'friends'我不太确定它被初始化为什么,可能只是一个空向量,但我不确定
Test(std::string name,std::vector friends):name{name},friends{friends}{}//代码块中不需要任何代码——这就是它的名称吗?或者只是代码括号?或者什么?lol
//复制构造函数
Test(const-Test&source):name{source.name},friends{source.friends}{}//同样,不需要在中使用任何额外的代码--不管调用什么--
//移动构造函数
Test(Test&&source)无异常:name{source.name},friends{source.friends}{}
//析构函数
~Test(){}//不需要自己定义一个,但我只是这样离开了,只是删除了“delete”语句
};
当我看上面的代码时,我想不出Move构造函数比copy-copy构造函数更快、更高效。在这种情况下,我想不出如何使Move构造函数更快/更高效

可能被回答的问题除了上述守则或其中一段中已经提出的一些问题外,如果守则评论或段落中的问题也能得到回答,我将不胜感激:

  • 我的两个类定义都正确吗?如果不正确,哪些是/不正确,为什么
  • 对于第二个类
    Test
    定义,有没有办法使Move构造函数更快
  • 我的思维过程与正确答案相符吗?换句话说,Move构造函数是有限的,并且与
    Test
    类的第二个定义中的Copy构造函数相比不会更快吗
  • 移动构造函数“总是”比复制构造函数更有效吗

    两者都可以有自定义实现,所以“邪恶”类可能会进行低效的移动和正确的复制

    对于常规类,
    move
    应该比copy更有效或等效

    当我看上面的代码时,我想不出Move构造函数比copy-copy构造函数更快、更高效。在这种情况下,我想不出如何使Move构造函数更快/更高效

    你的移动代码是。。副本应为:

    class Test {
    
        std::string name;
        std::vector<std::string> friends;
    
        Test() : name{}, friends{} {} // empty string, empty vector.
    
        Test(std::string name, std::vector<std::string> friends) : name{std::move(name)}, friends{std::move(friends)} {}
    //                                                                  ^^^^^^^^^^                ^^^^^^^^
        // Copy constructor
        Test(const Test &source) : name{source.name}, friends{source.friends} {}
        // or simply Test(const Test &) = default;
    
        // Move constructor
        Test(Test &&source) noexcept : name{std::move(source.name)}, friends{std::move(source.friends)} {}
        //                                  ^^^^^^^^^                        ^^^^^^^^
        // or simply Test(Test &&) = default;
    
        // Destructor
        ~Test() = default;
    };
    
    类测试{
    std::字符串名;
    病媒朋友;
    Test():name{},friends{}{}//空字符串,空向量。
    Test(std::string name,std::vector friends):name{std::move(name)},friends{std::move(friends)}{}
    //                                                                  ^^^^^^^^^^                ^^^^^^^^
    //复制构造函数
    Test(consttest&source):name{source.name},friends{source.friends}{
    //或者简单地测试(const Test&)=默认值;
    //移动构造函数
    Test(Test&&source)noexcept:name{std::move(source.name)},friends{std::move(source.friends)}{}
    //                                  ^^^^^^^^^                        ^^^^^^^^
    //还是简单