Memberwise copy(深拷贝)与Bitwise copy(浅拷贝)的区别

转自:http://blog.csdn.net/sghcpt/article/details/5578320

又加了一些自己补充。

原文:

Memberwise copy: 在初始化一个对象期间,基类的构造函数被调用,成员变量被调用,如果它们有构造函数的时候,它们的构造函数被调用,这个过程是一个递归的过程.
Bitwise copy: 原内存拷贝.例子,给定一个对象object,它的类型是class Base.对象object占用10字节的内存,地址从0x0到0x9.如果还有一个对象objectTwo,类型也是class Base.那么执行objectTwo = object;如果使用Bitwise拷贝语义,那么将会拷贝从0x0到0x9的数据到objectTwo的内存地址,.也就是说Bitwise是字节到字节的拷贝.

对于默认的拷贝构造函数不会使用深拷贝,它只是使用浅拷贝.这意味着类的所有的成员是一层深度的拷贝而已。如果你的类或结构体成员中只是包含基本的数据类型例如int, float, char,那么Memberwise copy与Bitwise copy基本是相同的。但如果类中有指针存在,那么你可能会遇到问题。
例如下面的例子:
class A
{
   int m1;
   double d1;
   char* pString;
};
如果你创建两个这样的类对象,class A  a, b;并且你给a赋值,
a.mi = 6;
a.d1 = 10.123;
a.pString = new char[10];
astrcpy(a.pString, "test");//这里是浅拷贝
如果执行b = a;那么会把对象a的每一个成员的值赋值给b的每个成员。
b.m1 = a.m1;
b.d1 = a.d1;
b.pString = a.pString;//现在对象a和b的成员pString都执向相同的内存,删除任一个内存都会析放另一个对象的内存。
所以你需要深拷贝,它不是拷贝的内存地址而是拷贝内存地址的内容。一个默认的拷贝构造函数经常执行浅拷贝,只有拥有
自己的拷贝函数才可以实现深拷贝。


补充:

在BitWise Copy Sematics中,因为是按位拷贝的(内存复制),所以那些整数、数组等都会拷贝,新得到的类和原来的类完全一样。但是需要注意一点,如果有指针时,例如

Class Test{

……;

char * p;

};

Test B=A;//A是Test类的对象

这时候如果是BitWise Copy,那么A和B中的指针p就会指向同一内存,如果内存在构造函数中释放,那么另一个类的指针将失效。


在一下4中情况,不要BitWise Copy

1、当Class内的成员变量是一个类,这各类声明了Copy Constructor(不是编译器默认合成)时。

2、当Class继承自一个Base Class时,而Base Class存在Copy Constructor时(不是编译器默认合成)。

3、当Class中声明有virtual function时

4、当Class继承自一个继承串链,其中一个或多个virtual Base Class时。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 C 语言中,可以使用成员初始化列表来初始化结构体的成员。这种方法叫做成员初始化(memberwise initialization)。 例如,我们可以使用下面的代码来定义一个名为 `Person` 的结构体,并使用成员初始化列表来初始化它的成员: ``` struct Person { char *name; int age; char *address; }; struct Person p = { "John", 30, "New York" }; ``` 在这个例子中,我们使用了成员初始化列表来初始化 `Person` 结构体的三个成员:`name`、`age` 和 `address`。 我们也可以在使用成员初始化列表时省略结构体名,例如: ``` struct Person p = { "John", 30, "New York" }; ``` 在这种情况下,编译器会自动推断出结构体的类型。 希望这对你有帮助! ### 回答2: 在C语言中,结构体(struct)是一种自定义的数据类型,它可以由不同类型的变量组成。Memberwise Initialization是一种初始化结构体的方法,可以一次性为结构体中的每个成员变量赋初值。 例如,我们有一个结构体表示一个学生的信息: ```c struct Student { char name[20]; int age; float score; }; ``` 通过使用Memberwise Initialization,我们可以在定义结构体变量的同时为其成员变量赋初值。例如: ```c struct Student stu = {"Tom", 18, 90.5}; ``` 在上述代码中,我们定义了一个名为stu的结构体变量,并使用Memberwise Initialization为其成员变量赋初值。其中,name成员变量被初始化为"Tom",age成员变量被初始化为18,score成员变量被初始化为90.5。 这样,我们就可以一次性为结构体的每个成员变量赋初值,而不需要逐个赋值。这种方法在初始化结构体变量时非常方便,尤其是当结构体的成员变量较多时。 需要注意的是,Memberwise Initialization只能在定义结构体变量时使用,不能在之后对已存在的结构体变量进行赋值。 ### 回答3: 在C语言中,可以使用成员初始化列表进行成员初始化的操作。 例如,定义一个名为Student的结构体,包含姓名(name)、年龄(age)和成绩(score)三个成员变量。 ```c #include <stdio.h> typedef struct { char name[20]; int age; float score; } Student; int main() { // 成员初始化列表的示例 Student student = { "Tom", 18, 89.5 }; // 输出学生信息 printf("姓名:%s\n", student.name); printf("年龄:%d\n", student.age); printf("成绩:%.1f\n", student.score); return 0; } ``` 在上述代码中,我们通过成员初始化列表的方式对Student结构体的成员进行了初始化。声明和定义一个名为student的Student结构体变量,并在初始化列表中分别为name、age和score赋予了初始值。 最后,通过printf函数将学生的姓名、年龄和成绩输出到控制台上。 这样,我们就成功地使用了成员初始化列表来进行C语言中的成员初始化操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值