为什么我的代码中没有调用移动构造函数?还有为什么不调用 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 elision,g1
是使用构造函数构造的。为了移动构造 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 实施。
我的代码行
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 elision,g1
是使用构造函数构造的。为了移动构造 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 实施。