C++:除非调用显式强制转换,否则不调用Move构造函数



我创建了一个类,"ListElement";,其包含类"的实例作为单个数据变量;MyClass";其包含动态分配的阵列。

  • 对于ListElement,我创建了一个默认构造函数,它委托给一个初始化MyClass实例的右值构造函数。

  • 对于MyClass,我创建了一个构造函数,它将数组初始化为输入值(以及一个默认构造函数,它委托给上面的值为0的构造函数(。此外,我还包含了一个副本和一个移动构造函数。

然而,我很困惑,为什么不调用move构造函数,除非数据类型被显式地转换为r值引用,尽管它已经按原样传递了(见下文(。

#include <iostream>
template <int arrSize>
class MyClass {
private:
// Data
int* a;
public:
//Constructor
MyClass(int value){
this->a = new int[arrSize];
for(unsigned int i = 0; i<arrSize; ++i){
a[i] = value;
}
std::cout << "MyClass created!" << std::endl;
}
MyClass(): MyClass(0){}
//Copy  Constructor
MyClass(const MyClass<arrSize>& other){
this->a = new int[arrSize];
for(unsigned int i = 0; i<arrSize;++i){
a[i] = other.a[i];
}
std::cout << "MyClass copied!" << std:: endl;
}
//Move Constructor
MyClass(MyClass<arrSize>&& other){
this->a = other.a;
other.a = nullptr;
std::cout << "MyClass moved!" << std::endl;
}
//Destructor
~MyClass(){
delete[] this->a;
std::cout << "MyClass deleted!" << std::endl;
}
};
class ListElement {
public:
//Constructors
ListElement(MyClass<5>&& data) : data((MyClass<5>&&)data) {} // QUESTION 
ListElement(): ListElement(MyClass<5>(1)){}
private:
//Data
MyClass<5> data;
};
int main() {
ListElement myZeroListElement{};
return 0;
}

问题:如果我为这一行编写,为什么要调用复制构造函数(请参阅注释(?

ListElement(MyClass<5>&& data) : data(data) {}

"数据";是一个正确的值引用,但只有当我解释性地将move构造函数强制转换为这样的正确值引用时,才会调用它:

ListElement(MyClass<5>&& data) : data((MyClass<5>&&)data) {}

非常感谢!

问题1

因为data而不是右值。R值为无名称data是一个名称⇒不是右值。命名右值引用是绑定到右值的引用,但它们本身不是右值。

你的演员阵容是正确的,但不是通用的,也不是惯用的。标准库提供std::move正是为了这个目的,请使用它

问题2

我认为应该在指向已分配数据的指针的初始化列表中对其进行初始化。所有内容都应在初始化列表中进行初始化。如果这是不可能的,那么你的设计可能有问题。

MyClass(int value): a(new int[arrSize]) { ... }

当然,在实际代码中,您应该使用std::vectorstd::array

问题3

大小不是动态定义的。它必须在编译时已知。

最新更新