未调用移动构造函数
move Constructor is not called
我正在实现一个 IntArray Class 来学习 C++。我必须承认我还没有完全理解 r 和左值以及移动构造函数。我想试试看我的代码是否有效,但我不知道为什么
{IntArray array = IntArray(5);}
没有调用我实现的移动构造函数。我认为这是一个案例。
#include "IntArray.h"
IntArray::IntArray()
:data(nullptr), count(0), capacity(0) {std::cout << "Default Constructor called" << std::endl;}
IntArray::IntArray(int size)
:data(new int[size]), count(size), capacity(size) {std::cout << "Constructor called with size: " << size << std::endl;}
IntArray::~IntArray() {
std::cout << "Destructor called" << std::endl;
delete[] data; //rest is stack allocated and gets freed with end of scope
}
//COPY CONSTRUCT & ASSIGN OP
IntArray::IntArray(const IntArray& rhs)
:data(new int[rhs.count]), count(rhs.count), capacity(rhs.count) //warum nicht mit capacity? wir wollen doch eine exakte kopie?
{
std::cout << "Copy Constructor called" << std::endl;
std::copy(rhs.data, rhs.data + rhs.count, data); //pointer arithmetik?
}
IntArray& IntArray::operator=(const IntArray& rhs) {
if (&rhs == this) //check for selfassign
return *this;
//if capacity of lhs is NOT big enough, reallocate new
if (capacity < rhs.capacity) {
delete[] data;
data = new int[rhs.count];
capacity = rhs.count;
}
count = rhs.count;
std::copy(rhs.data, rhs.data + rhs.count, data);
return *this;
}
//MOVE CONSTRUCT & ASSIGN OP
IntArray::IntArray(IntArray&& rhs)
:data(rhs.data), count(rhs.count), capacity(rhs.capacity)
{
std::cout << "Move Constructor called" << std::endl;
rhs.data = nullptr;
rhs.count = 0;
rhs.capacity = 0;
}
IntArray& IntArray::operator=(IntArray&& rhs) {
if (&rhs == this) //self assignment?
return *this;
std::cout << "Move assignment operator called" << std::endl;
//steal
delete[] data;
data = rhs.data;
count = rhs.count;
capacity = rhs.capacity;
//Reset old obj to prevent double freeing
rhs.data = nullptr;
rhs.count = 0;
rhs.capacity = 0;
return *this;
}
您看不到移动构造或移动分配只是优化的结果!请查看 "copy elision" https://en.cppreference.com/w/cpp/language/copy_elision
如果您使用的是 gcc,您可以通过以下方式告诉编译器不要对其进行优化:
g++ -O0 main.cpp -fno-elide-constructors
现在的结果是:
Constructor called with size: 5
Move Constructor called
Destructor called
Destructor called
我正在实现一个 IntArray Class 来学习 C++。我必须承认我还没有完全理解 r 和左值以及移动构造函数。我想试试看我的代码是否有效,但我不知道为什么
{IntArray array = IntArray(5);}
没有调用我实现的移动构造函数。我认为这是一个案例。
#include "IntArray.h"
IntArray::IntArray()
:data(nullptr), count(0), capacity(0) {std::cout << "Default Constructor called" << std::endl;}
IntArray::IntArray(int size)
:data(new int[size]), count(size), capacity(size) {std::cout << "Constructor called with size: " << size << std::endl;}
IntArray::~IntArray() {
std::cout << "Destructor called" << std::endl;
delete[] data; //rest is stack allocated and gets freed with end of scope
}
//COPY CONSTRUCT & ASSIGN OP
IntArray::IntArray(const IntArray& rhs)
:data(new int[rhs.count]), count(rhs.count), capacity(rhs.count) //warum nicht mit capacity? wir wollen doch eine exakte kopie?
{
std::cout << "Copy Constructor called" << std::endl;
std::copy(rhs.data, rhs.data + rhs.count, data); //pointer arithmetik?
}
IntArray& IntArray::operator=(const IntArray& rhs) {
if (&rhs == this) //check for selfassign
return *this;
//if capacity of lhs is NOT big enough, reallocate new
if (capacity < rhs.capacity) {
delete[] data;
data = new int[rhs.count];
capacity = rhs.count;
}
count = rhs.count;
std::copy(rhs.data, rhs.data + rhs.count, data);
return *this;
}
//MOVE CONSTRUCT & ASSIGN OP
IntArray::IntArray(IntArray&& rhs)
:data(rhs.data), count(rhs.count), capacity(rhs.capacity)
{
std::cout << "Move Constructor called" << std::endl;
rhs.data = nullptr;
rhs.count = 0;
rhs.capacity = 0;
}
IntArray& IntArray::operator=(IntArray&& rhs) {
if (&rhs == this) //self assignment?
return *this;
std::cout << "Move assignment operator called" << std::endl;
//steal
delete[] data;
data = rhs.data;
count = rhs.count;
capacity = rhs.capacity;
//Reset old obj to prevent double freeing
rhs.data = nullptr;
rhs.count = 0;
rhs.capacity = 0;
return *this;
}
您看不到移动构造或移动分配只是优化的结果!请查看 "copy elision" https://en.cppreference.com/w/cpp/language/copy_elision
如果您使用的是 gcc,您可以通过以下方式告诉编译器不要对其进行优化:
g++ -O0 main.cpp -fno-elide-constructors
现在的结果是:
Constructor called with size: 5
Move Constructor called
Destructor called
Destructor called