移动语义机制 我已经开始学习C++,但是我对移动语义有一些怀疑。当书中说A的move构造函数“窃取”右值B的属性时,是不是意味着指向V值的指针从B切换到A?这样,A就不需要分配另一部分内存了
如果是的话,为什么在这个代码中移动语义机制 我已经开始学习C++,但是我对移动语义有一些怀疑。当书中说A的move构造函数“窃取”右值B的属性时,是不是意味着指向V值的指针从B切换到A?这样,A就不需要分配另一部分内存了,c++,move-semantics,C++,Move Semantics,如果是的话,为什么在这个代码中 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): si
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;
类CBuffer{
私人:
整数大小;
int csize;
char*ptr;
字符rtp;
公众:
CBuffer(int size):大小(size),csize(0){
ptr=新字符[大小];
*ptr='a';
}
CBuffer(constcbuffer&source):大小(3),csize(source.csize){
此->ptr=新字符[大小];
memcpy(this->ptr,source.ptr,size);
}
CBuffer(CBuffer&源){
此->ptr=source.ptr;
此->大小=source.size;
move语义意味着,我们不创建另一个对象的副本,而是允许该对象获取该另一个对象内部任何动态分配的内存
我们通过在两者之间交换任何动态分配的内存来实现这一点,这意味着值(这意味着存储在指针中的内存地址)第一个对象中指针的值现在将是新对象中指针的值,我们在右值引用中放置了一个null ptr,因此当它被销毁时,它也会销毁它
我在代码中添加了一些内容:
我已经初始化了初始值设定项列表中的所有变量。此外,我还删除了副本中大小的硬编码初始化
在复制/移动操作中,通常为其他对象使用“其他”名称
一个错误:您必须在ptr中放入一个值,不初始化变量是一种不好的做法。实际上,如果我们添加一个dtor,并在此处使用交换习惯用法(解释如下),则会导致无效的删除
最后但并非最不重要的一点是,可以对活动对象调用move-ctor,而不是删除当前ptr,而是将nullptr放在其他ptr上,这意味着永远不会删除该ptr。例如,如果main是:
交换成语对我们有什么帮助
让我们看一看我的例子;当我们交换值(意思是a.ptr=old b.ptr
和b.ptr=old a.ptr
)时,每当b被删除时,现在驻留在b中的“old”a.ptr就会被删除,因为我们只是交换了它们。通常,当我们使用移动语义时,rvalue很快就会被破坏,我们只是“骑”对其进行销毁,以防止内存泄漏
您的代码应该是这样的(添加了一些打印以便更好地理解):
它打印的是指针的地址,而不是指针的值。&this->ptr
和&source.ptr
是指针的地址变量。而不是指针指向的对象的地址。当它从B“偷走”内存时,为什么需要分配更多内存?那太贪婪了。我认为source
或者src
也是一个非常常见的名称,实际上描述了它的含义。我只遇到过其他名称,在中也是这样。总之,我对自己说,有些使用源代码。
std::cout << &this->ptr << std::endl;
std::cout << &source.ptr << std::endl;
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!
}
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