0%

C++ 关于对象的复制

本文探讨了C++中对象复制的机制,重点介绍了拷贝构造函数和拷贝赋值运算符的使用。文章指出,虽然memsetmemcpy在某些情况下可以用于初始化或复制对象,但它们仅适用于POD(Plain Old Data)类型,否则可能导致未定义行为。对于非POD类型,推荐使用构造函数、成员函数(如clear())或STL算法(如std::fillstd::copy)来安全地初始化和复制对象。文章通过代码示例和外部参考链接,帮助读者理解如何正确管理对象的内存和复制行为。

通常我们使用对象内的拷贝构造函数和拷贝构造符来进行初始化和拷贝。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class A
{
public:
/// 拷贝构造函数
A(const A& other)
{
i = other.i;
vec = other.vec;
}

/// 拷贝赋值符
A& operator=(const A& other)
{
if(this != &other)
{
i = other.i;
vec = other.vec;
}
return *this;
}
private:
int i;
std::vector<int> vec;
};

A foo;
A bar(foo); ///< 在这里调用拷贝构造函数
A bar2;
bar2 = foo; ///< 这里调用拷贝赋值符

关于memset

首先说结论,不推荐使用memset对某个对象进行擦写内存。因为可能导致未定义行为。
具体可以查看stackflow上的这个问题 memset for initialization in C++Use memset or a struct constructor? What’s the fastest?

你可以使用构造函数进行初始化,也可以定义成员函数clear(), 或是使用std::fill, std::fill_n
在使用函数memset时,有部分限定条件,只有目标对象为POD类型才可以使用。

简单来说就是,该对象如果没有继承,都是基础类型(如: intchar或其他POD类型), 没有包含如std::array, std::vector等STL容器, 该对象可以称为POD类型。如下面示例

1
2
3
4
5
6
7
class pod
{
char ac[12];
int i;
float f;
long l;
};

关于POD具体查看C++ named requirements: PODType

关于memcpy

结论是,不推荐使用,同样除了你能确保该对象为POD类型,否则则会导致未定义现象。
可以使用拷贝构造函数或拷贝赋值符,或是std::copystd::copy_n来代替memcpy;