我目前正在用C ++编写自己的字符串实现。 (仅供锻炼)。
但是,我目前有这个拷贝构造函数:
memcpy()
我希望稍微提高性能。因此,我使用obj
提出了将*this
复制到// "obj" has the same type of *this, it's just another string object
string_base<T>(const string_base<T> &obj) {
memcpy(this, &obj, sizeof(string_base<T>));
}
的想法。
就像那样:
*this
像这样覆盖web.xml
的数据是否安全?或者这会产生任何问题吗?
提前致谢!
答案 0 :(得分:3)
不,这不安全。来自cppreference.com:
如果对象不是
TriviallyCopyable
,则memcpy
的行为未指定,可能未定义。
您的班级不是TriviallyCopyable
,因为其复制构造函数是用户提供的。
此外,您的复制构造函数只会生成浅层副本(如果您需要,可能没问题,例如,应用了字符串的写时复制机制)。
答案 1 :(得分:2)
会产生问题。所有引用和指针都将被复制,甚至是指向raw_data的指针,它将与源对象相同。
作为使用memcpy的必备条件,您的课程应该:
答案 2 :(得分:1)
正如其他人所说,为了使memcpy
正常工作,被复制的对象必须是可以轻易复制的。对于模板中T
这样的任意类型,您无法确定。当然,你可以检查它,但让其他人做检查要容易得多。不要编写那个循环并调整它,而是使用std::copy_n
。如果适当的话,它将使用memcpy
,而当它不是时,它将逐个元素地复制。所以改变
raw_data = new T[cap];
for (unsigned i = 0; i < cap; i++)
raw_data[i] = obj.data()[i];
到
raw_data = new T[cap];
std::copy_n(obj.data(), cap, raw_data);
这也有一点点优点就是不会在循环的每次传递中评估obj.data()
,这是编译器可能适用或不适用的优化。
答案 3 :(得分:0)
从raw_data
是成员的有限片段和指向new[]
的{{1}}数组的指针看起来非常明显。如果你memcpy对象,你memcpy这个指针。你没有复制数组。
看看你的析构函数。它可能无条件地调用T
。它不知道有多少副本存在。这意味着它经常调用delete[]
。这是可以解决的:您需要类似delete[]
的内容。这根本不是微不足道的;你必须担心该份额的线程安全性。显然,您不能只是shared_ptr
该对象,因为这不会更新共享计数。