如何解决移动运算符破坏原始指针
我正在尝试使用指向内存位置的指针。 然后,如果我修改原始分配的变量 指向同一位置的人也必须受到变化的影响。
a = Data("New data");
编辑:我知道以下内容:
- std::shared_ptr
- std::make_shared
但是,我试图在没有这些新功能的情况下实现这一点。我完全知道。
我的 C++ 代码:
class Data
{
private:
char* local_data;
int _size = 0;
int length(const char* c)
{
int i = 0;
while(c[++i] != '\0');
return i;
}
public:
Data() {
local_data = new char[_size];
}
Data(const char* cdata){
_size = length(cdata);
local_data = new char[_size];
memcpy(local_data,cdata,_size);
}
int size() { return _size; }
char* data() { return local_data; }
const char* data() const { return local_data; }
Data& operator=(const Data& data){}
Data& operator=(Data&& data){
if(this == &data)
return *this;
_size = std::move(data.size());
local_data = std::move(data.data());
return *this;
}
};
int main(){
Data a("Some data");
auto dptr = a.data(); // Gives a pointer to the original location
a = Data("New data"); // Must modify both a and dptr
assert(dptr == a.data()); // Should pass successfully,else fail
return 0;
}
解决方法
您似乎想要std::shared_ptr<std::string>
:
class Data
{
private:
std::shared_ptr<std::string> local_data = std::make_shared<std::string>();
public:
Data() = default;
Data(const char* cdata) : local_data(std::make_shared<std::string>(cdata)) {}
int size() const { return local_data->size(); }
char* data() { return local_data->data(); }
const char* data() const { return local_data->c_str(); }
Data operator=(const Data& rhs) {
if (this == &data)
return *this;
*local_data = *rhs.local_data;
return *this;
}
};
int main(){
Data a("Some data");
auto dptr = a.data(); // Gives a pointer to the original location
a = Data("New data"); // Must modify both a and dptr
assert(dptr == a.data()); // Should pass successfully
}
,
您的 class Data
存在一些问题。首先,它从不调用 delete[] local_data
,因此会泄漏内存。添加析构函数:
~Data() {
delete[] local_data;
}
然后确保您的移动赋值运算符正常工作。不要使用std::move(data.data())
,这实际上不会设置从移动到nullptr
的对象中的指针。此外,请确保正确清理 this->local_data
。最简单的方法是:
Data& operator=(Data&& data){
std::swap(local_data,data.local_data);
std::swap(_size,data._size);
return *this;
}
它交换了指针,所以没有内存泄漏。移动后,销毁 data
将确保删除旧的 this->local_data
。
你的复制赋值运算符是空的,你应该解决这个问题,如果你有一个移动赋值运算符,你可能还想实现一个移动构造函数。最后:
assert(dptr == a.data()); // Should pass successfully,else fail
这是错误的; dptr
不应与 a.data()
相同,因为 dptr
是指向移动分配之前获取的数据的指针的副本。除非您明确修改 dptr
,否则 dptr
的值不会改变。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。