作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一类与char指针。我想知道在没有显式定义副本构造函数的情况下怎么可能进行副本构造?
我认为是因为对象已经被分配了,但是如果是这样,那为什么有人首先需要复制构造函数呢?
#include <iostream>
#include <cstring>
class Data {
public:
explicit Data(const char* newData)
:size{strlen(newData)},
data{size ? new char[size] : nullptr}
{
std::memcpy(data, newData, size);
}
friend std::ostream& operator<<(std::ostream& ost, const Data& rhs) {
for (std::size_t i = 0; i < rhs.size; i++) {
std::cout << rhs.data[i];
}
ost << "\n";
return ost;
}
~Data() {
delete[] data;
}
private:
std::size_t size;
char* data;
};
int main() {
Data data1{"data1"};
Data data2{data1}; // copy constructor
std::cout << data1;
std::cout << data2;
return 0;
}
data1
data1
Data(const Data& other) {
if (this != &other) {
size = other.size;
data = new char[size];
std::memcpy(data, other.data, size);
}
}
最佳答案
从C++ 11开始,如果类具有用户定义的析构函数,则不建议使用implicitly-defined copy constructor生成,但是仍然会生成。该复制构造函数将只复制size
和data
,从而进行浅拷贝,而不是深表复制。这是一条通往灾难的道路,因为在原始对象及其副本被销毁时,data
随后将被多次删除。
例如,如果您在Valgrind下运行原始代码,则会看到以下报告:
==9908== HEAP SUMMARY:
==9908== in use at exit: 0 bytes in 0 blocks
==9908== total heap usage: 3 allocs, 4 frees, 73,733 bytes allocated
==9908==
==9908== All heap blocks were freed -- no leaks are possible
==9908==
==9908== For counts of detected and suppressed errors, rerun with: -v
==9908== ERROR SUMMARY: 18 errors from 9 contexts (suppressed: 0 from 0)
Data
是可复制的,则必须提供一个深度复制构造函数,该构造函数分配新的存储并将数据复制到其中。您问题中的一个看起来几乎(*)很好:
==9993== HEAP SUMMARY:
==9993== in use at exit: 0 bytes in 0 blocks
==9993== total heap usage: 4 allocs, 4 frees, 73,738 bytes allocated
==9993==
==9993== All heap blocks were freed -- no leaks are possible
==9993==
==9993== For counts of detected and suppressed errors, rerun with: -v
==9993== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Data(const Data&) = delete;
other.data
可以是
nullptr
,因此您在复制之前先
have to check it:
void* memcpy(void* dest, const void* src, std::size_t count);
If either
dest
orsrc
is a null pointer, the behavior is undefined, even ifcount
is zero.
关于c++ - C++成功复制动态分配的obj,而无需复制ctor?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59658165/
我是一名优秀的程序员,十分优秀!