使用此指针的memcpy安全吗? 我现在正在用C++编写一个自己的字符串实现。(只是为了锻炼)

使用此指针的memcpy安全吗? 我现在正在用C++编写一个自己的字符串实现。(只是为了锻炼),c++,arrays,memcpy,this-pointer,C++,Arrays,Memcpy,This Pointer,但是,我目前拥有此副本构造函数: // "obj" has the same type of *this, it's just another string object string_base<T>(const string_base<T> &obj) : len(obj.length()), cap(obj.capacity()) { raw_data = new T[cap]; for (unsigned i = 0; i &

但是,我目前拥有此副本构造函数:

// "obj" has the same type of *this, it's just another string object
string_base<T>(const string_base<T> &obj)
        : len(obj.length()), cap(obj.capacity()) {
    raw_data = new T[cap];
    for (unsigned i = 0; i < cap; i++)
        raw_data[i] = obj.data()[i];
    raw_data[len] = 0x00;
}
像那样覆盖
*此
的数据安全吗?或者这会产生什么问题


提前谢谢

它将产生问题。所有引用和指针都将被复制,甚至是指向原始数据的指针,这些数据将与源对象相同

作为使用memcpy的必要条件,您的班级应该:

  • 没有引用或指针,除非:静态指针或不拥有指向的数据。除非您知道自己在做什么,比如实现写时拷贝机制,或者这种行为是在其他情况下有意和管理的

  • 不,这不安全。从cppreference.com:

    如果对象不可
    普通可复制
    ,则不会指定
    memcpy
    的行为,并且可能未定义

    您的类不是可复制的,因为它的复制构造函数是用户提供的



    此外,您的复制构造函数将只进行浅层复制(如果您愿意,这可能很好,例如,字符串应用的写时复制机制)。

    从有限的片段中可以明显看出,
    原始数据是一个成员,并且是指向
    新[]
    ed数组
    T
    的指针。如果memcpy对象,则memcpy此指针。不复制数组


    看看你的析构函数。它可能会无条件地调用
    delete[]
    。它不知道有多少份。这意味着它调用
    delete[]
    的频率太高。这是可以解决的:您需要类似于
    shared\u ptr
    的东西。这一点都不微不足道;您必须担心共享计数的线程安全性。显然,您不能只
    memcpy
    对象,因为这不会更新共享计数

    正如其他人所说,为了使
    memcpy
    正常工作,被复制的对象必须是可复制的。对于模板中的任意类型,如
    T
    ,您无法确定这一点。当然,你可以检查一下,但是让别人检查要容易得多。使用
    std::copy\n
    ,而不是编写循环并对其进行调整。如果合适,它将使用
    memcpy
    ,如果不合适,它将使用逐元素复制。所以改变

    raw_data = new T[cap];
    for (unsigned i = 0; i < cap; i++)
        raw_data[i] = obj.data()[i];
    

    这还有一个小小的优点,就是不必在每次循环中都计算
    obj.data()
    ,这是一种编译器可能会也可能不会应用的优化;几乎是重复的:您还可以使用strcpy,它在空字符处停止。与MimcPype相比,它的性能可能有所不同。要考虑的另一件事是,现代编译器往往足够聪明,能够识别第一个示例中的循环,并在适当的时候用MeMCPY替换它。所以这可能是一个过早的优化。顺便说一句,你只需要复制
    len
    对象,而不是
    cap
    。“平凡可复制”是什么意思?我不确定简单可复制就足够了,尽管这是必要的。@codekaizer一点也不:
    std::cout@DanielLangr,是的,刚刚读过。基于注释-std::string在c++14和onwards@codekaizer不,请阅读下一条评论:“包含
    std::string
    的对象从来都不是可复制的对象”。如果指针不拥有所指向的数据,那么指针就可以了。否则,我们会多次删除同一个内存。。。@Aconcagua说了些什么。已编辑。当然,它们也可以被引用。至于写时复制机制。这就是为什么我会小心如此强烈的声明。好吧,我又编辑了一次,但这应该是它。关于引用和指针的警告是强制性的。如果您有引用成员,并且执行
    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);