我已经开始学习C ++,但对移动语义有些疑问。当这本书说A的move构造函数“窃取”右值B的属性时,是否意味着指向值V的指针从B切换到A?因此,通过这种方式,A不需要分配内存的另一部分?
如果是这样,为什么在此代码中
class CBuffer{
private:
int size;
int csize;
char* ptr;
char rtp;
public:
CBuffer(int size): size(size), csize(0){
ptr = new char[size];
*ptr = 'a';
}
CBuffer(const CBuffer& source): size(3), csize(source.csize) {
this->ptr = new char[size];
memcpy(this->ptr, source.ptr, size);
}
CBuffer(CBuffer&& source){
this->ptr = source.ptr;
this->size = source.size;
std::cout << &this->ptr << std::endl;
std::cout << &source.ptr << std::endl;
source.ptr = nullptr;
}
};
int main(){
CBuffer a = CBuffer(1);
CBuffer b = std::move(a);
CBuffer c = b;
行
std::cout << &this->ptr << std::endl;
std::cout << &source.ptr << std::endl;
打印不同的地址?
移动语义意味着我们无需创建另一个对象的副本,而是允许该对象获取此另一个对象内部的任何动态分配的内存。
我们通过在两者之间交换任何动态分配的内存来做到这一点,这意味着value(意味着存储在指针中的内存地址)现在,第一个对象中的指针将是新对象中指针的[value,并且我们在rvalue引用中放置了nullptr,因此当销毁它时,它也会销毁它。
我在代码中添加了一些内容:
int main()
{
CBuffer a{1};
CBuffer b{2};
a = std::move(b); // legal, but causes memory leak in your code, the value of a.ptr is never deleted!
}
交换习语如何帮助我们?!
让我们看看我的例子;当我们交换值(表示a.ptr = old b.ptr
和b.ptr = old a.ptr
)时,无论何时删除b,现在驻留在b中的“旧” a.ptr都将被删除,因为我们只是交换了它们。通常,当我们使用move语义时,右值将很快被销毁,我们只是“骑乘”其销毁以防止内存泄漏。
您的代码应该看起来像这样(添加了一些图片以更好地理解):
class CBuffer{
private:
int size = 0;
int csize = 0;
char* ptr = nullptr; // very important!!!
char rtp = 0;
int id = 0;
public:
static int get_current_count()
{
static int object_cnt = 1;
return object_cnt++;
}
CBuffer(int size) :
size(size),
csize(0),
ptr(new char[size]),
rtp(0)
{
id = get_current_count();
std::cout << "On ctor of " << id << std::endl;
ptr[0] = 'a';
}
CBuffer(const CBuffer& other) :
size(other.size),
csize(other.csize),
ptr(new char[size]),
id(get_current_count())
{
std::cout << "On copy ctor of " << other.id << " to " << this->id << std::endl;
std::memcpy(this->ptr, other.ptr, size);
}
CBuffer(CBuffer&& other) :
size(other.size),
csize(other.csize),
rtp(other.rtp),
id(get_current_count())
{
std::cout << "On move ctor of " << other.id << " to " << this->id << std::endl;
std::swap(this->ptr, other.ptr);
}
~CBuffer()
{
std::cout << "On dtor of " << id << std::endl;
delete[] ptr;
}
};
int main()
{
CBuffer a = CBuffer(1);
CBuffer b = std::move(a);
CBuffer c = b;
}
输出为:
On ctor of 1
On move ctor of 1 to 2
On copy ctor of 2 to 3
On dtor of 3
On dtor of 2
On dtor of 1