c++ 深拷贝 浅拷贝,c拷贝构造函数详解
对于常见类型的对象,在它们之间进行复制很简单,例如:
int a=88
int b=a;
但是类对象不同于普通对象,类对象的内部结构一般比较复杂,成员变量多种多样。让我们看一个简单的类对象复制的例子。
#包括iostream
使用命名空间std
c类示例{
私人:
int a;
公共:
ce example(int b)
{ a=b;}
无效显示()
{
cout a endl
}
};
int main()
{
范例A(100);
c example B=A;
B.show();
返回0;
}运行程序,屏幕输出100。从上面代码的运行结果可以看出,系统为对象B分配内存,用对象a完成复制过程,就类对象而言,同类型的类对象通过复制构造函数完成整个复制过程。下面是复制构造函数工作原理的一个例子。
#包括iostream
使用命名空间std
c类示例{
私人:
int a;
公共:
ce example(int b)
{ a=b;}
示例(常量示例C)
{
a=C.a
}
无效显示()
{
cout a endl
}
};
int main()
{
范例A(100);
c example B=A;
B.show();
返回0;
} CExample(const CExample C)是我们自定义的复制构造函数。可以看出,复制构造函数是一个特殊的构造函数,函数名必须与类名一致。它唯一的参数是这种类型的引用变量,是const类型,不可变的。例如,类X的复制构造函数的形式是X(X x)。
当一个已初始化的自定义类类型对象被用来初始化另一个新构造的对象时,复制构造函数将被自动调用。也就是当需要复制类的对象时,会调用复制构造函数。在下列情况下会调用复制构造函数:
通过值传递的方式将对象传递到函数体中。
通过值传递从函数返回一个对象。
一个对象需要被另一个对象初始化。
如果复制构造函数没有在类中显式声明,编译器将自动生成一个默认的复制构造函数,它将在对象之间复制位。位拷贝也叫浅拷贝,后面会解释。
自定义复制构造函数是一种很好的编程风格,可以避免编译器形成默认的复制构造函数,提高源代码的效率。
浅拷贝和深拷贝
在某些情况下,类中的成员变量需要动态地打开堆内存。如果实现了位复制,那么一个对象中的值就被完整地复制到另一个对象中,比如A=B,这时如果B中的一个成员变量指针已经申请了内存,那么A中的那个成员变量也指向同一块内存。有一个问题:当B释放内存时(例如,destruct),A中的指针是一个野指针,导致运行错误。
深度复制和浅层复制可以简单理解为:如果一个类有资源,当这个类的对象被复制时,资源被重新分配,这个过程叫做深度复制;否则,如果不重新分配资源,则称为浅复制。这里有一个深度复制的例子。
#包括iostream
使用命名空间std
CA级
{
公共:
CA(int b,char* cstr)
{
a=b;
str=new char[b];
strcpy(str,CSTR);
}
加州(const CA C)
{
a=C.a
str=new char[a];//深层复制
if(str!=0)
strcpy(str,c . str);
}
无效显示()
{
cout str endl
}
~CA()
{
删除字符串;
}
私人:
int a;
char * str
};
int main()
{
CA A(10,“你好!”);
CA B=A;
B.show();
返回0;
}
深度拷贝和浅层拷贝的定义可以简单理解为:如果一个类有资源(堆或者其他系统资源),当这个类的对象被拷贝时,这个过程可以称为深度拷贝;另一方面,如果对象有资源,但复制进程没有复制资源,则被视为浅复制。
浅拷贝后释放资源时,资源的归属会不明确,导致程序运行出错。
Test(Test c_t)是一个用户定义的复制构造函数。复制构造函数的名称必须与类名一致。函数的形参是这种类型的引用变量,而且必须是引用。
当用已经初始化的自定义类类型对象初始化另一个新构造的对象时,将自动调用复制构造函数。如果你没有自定义的复制构造函数,系统会提供一个默认的复制构造函数来完成这个过程。复制上面代码的核心语句是通过Test(Test c_t)在构造函数中复制p1=c _ t.p1语句的完成。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。