为什么我的代码中没有调用移动构造函数?还有为什么不调用 dtor 只是为了销毁临时对象?

Why move constructor is not called in my code ? Also why dtor is not called just to destroy temp obj?

我的代码行

student g1(student("Larry"));//why move ctor is not called after overloaded ctor???
student g2 = "Delta";//Also here,why move ctor is not called after overloaded ctor???

另外,为什么 dtor 没有为刚刚创建的未命名临时对象调用????

实际上,当调用 move ctor 时,我完全感到困惑。 另一方面,我还观察到,如果我尝试将一个临时对象推回到一个期望对象类型元素的向量中,则会调用 move ctor,

vector<student> list{};
list.push_back(student("vickey"));

在这里,首先创建 vickey temp 对象,然后通过调用移动构造函数移动到 vector,因为 student("vickey") 是一个右值。不是吗?

如果上面是有效的那么为什么这里无效?

student g1(student("Larry"));
student g2 = "Delta";

这是我的代码

#include <iostream>
#include <cstring>
using namespace std;
//===================class declaration============================
class student{
private:
    char *name;
public:
    student();
    student(const char *str);
    ~student();
    student(student &&rhs) noexcept;
    
};
//======================impelmentation=========================
student::student(){
    cout<<"default"<<endl;
    name = new char[5];
    strcpy(name,  "None");
}
student::student(const char *str)
    :name{nullptr}{
        cout << "overloaded" << endl;
        if(str == nullptr){
            name = new char[5];
            strcpy(name, "None");
        }else{
        name = new char[strlen(str) + 1];
        strcpy(name, str);
        }
}

student::student(student &&rhs) noexcept
    :name{rhs.name}{
        cout << "Move ctor" << endl;
        rhs.name = nullptr;
        
}

student::~student(){
    if(name == nullptr)
        cout<<"dtor : nullptr"<< endl;
    else{
        cout<<"dtor : "<<name<< endl;
        delete [] name;
    }
}

//===================================main=====================================
int main() {
    student g1(student("Larry"));
    student g2 = "Delta";
    cout<<"\n=========================================================\n"<<endl;
    return 0;
}

输出:

overloaded
overloaded

=========================================================

dtor : Delta
dtor : Larry

这一行:

 student g1(student("Larry"));

由于copy elisiong1是使用构造函数构造的。为了移动构造 g1,您需要在这种情况下明确地执行此操作:

student g1(std::move(student("Larry")));

vec.push_back(student("vickey")); 的情况下调用移动构造函数,因为 std::vector 具有 push_back(T&&) 重载并且 student("vickey") 是右值。此重载解析导致调用类型的移动构造函数 (隐式地)。无法将对象 copying/moving 省略为 vector。所以,我们最多只能期待移动构造函数。

正如我们已经看到的,您可以在用户代码中执行类似的操作,方法是使用 std::move

注意,用户代码(通常)不应使用std::move。它主要用于 class 实施。