对于拷贝构造函数以及赋值构造函数的定义

合集下载

详解C++中构造函数,拷贝构造函数和赋值函数的区别和实现

详解C++中构造函数,拷贝构造函数和赋值函数的区别和实现

详解C++中构造函数,拷贝构造函数和赋值函数的区别和实现C++中⼀般创建对象,拷贝或赋值的⽅式有构造函数,拷贝构造函数,赋值函数这三种⽅法。

下⾯就详细⽐较下三者之间的区别以及它们的具体实现1.构造函数构造函数是⼀种特殊的类成员函数,是当创建⼀个类的对象时,它被调⽤来对类的数据成员进⾏初始化和分配内存。

(构造函数的命名必须和类名完全相同)⾸先说⼀下⼀个C++的空类,编译器会加⼊哪些默认的成员函数默认构造函数和拷贝构造函数析构函数赋值函数(赋值运算符)取值函数**即使程序没定义任何成员,编译器也会插⼊以上的函数!注意:构造函数可以被重载,可以多个,可以带参数;析构函数只有⼀个,不能被重载,不带参数⽽默认构造函数没有参数,它什么也不做。

当没有重载⽆参构造函数时,A a就是通过默认构造函数来创建⼀个对象下⾯代码为构造函数重载的实现<span style="font-size:14px;">class A{int m_i;Public:A(){Cout<<”⽆参构造函数”<<endl;}A(int i):m_i(i) {} //初始化列表}</span>2.拷贝构造函数拷贝构造函数是C++独有的,它是⼀种特殊的构造函数,⽤基于同⼀类的⼀个对象构造和初始化另⼀个对象。

当没有重载拷贝构造函数时,通过默认拷贝构造函数来创建⼀个对象A a;A b(a);A b=a; 都是拷贝构造函数来创建对象b强调:这⾥b对象是不存在的,是⽤a 对象来构造和初始化b的!!先说下什么时候拷贝构造函数会被调⽤:在C++中,3种对象需要复制,此时拷贝构造函数会被调⽤1. 1)⼀个对象以值传递的⽅式传⼊函数体2. 2)⼀个对象以值传递的⽅式从函数返回3. 3)⼀个对象需要通过另⼀个对象进⾏初始化什么时候编译器会⽣成默认的拷贝构造函数:1. 1)如果⽤户没有⾃定义拷贝构造函数,并且在代码中使⽤到了拷贝构造函数,编译器就会⽣成默认的拷贝构造函数。

C++拷贝(复制)构造函数详解

C++拷贝(复制)构造函数详解

C++拷贝(复制)构造函数详解⼀. 什么是拷贝构造函数⾸先对于普通类型的对象来说,它们之间的复制是很简单的,例如:[c-sharp]1. int a = 100;2. int b = a;⽽类对象与普通对象不同,类对象内部结构⼀般较为复杂,存在各种成员变量。

下⾯看⼀个类对象拷贝的简单例⼦。

[c-sharp]1. #include <iostream>2. using namespace std;3.4. class CExample {5. private:6. int a;7. public:8. //构造函数9. CExample(int b)10. { a = b;}11.12. //⼀般函数13. void Show ()14. {15. cout<<a<<endl;16. }17. };18.19. int main()20. {21. CExample A(100);22. CExample B = A; //注意这⾥的对象初始化要调⽤拷贝构造函数,⽽⾮赋值23. B.Show ();24. return 0;25. }运⾏程序,屏幕输出100。

从以上代码的运⾏结果可以看出,系统为对象 B 分配了内存并完成了与对象 A 的复制过程。

就类对象⽽⾔,相同类型的类对象是通过拷贝构造函数来完成整个复制过程的。

下⾯举例说明拷贝构造函数的⼯作过程。

[c-sharp]1. #include <iostream>2. using namespace std;3.4. class CExample {5. private:6. int a;7. public:8. //构造函数9. CExample(int b)10. { a = b;}11.12. //拷贝构造函数13. CExample(const CExample& C)14. {15. a = C.a;16. }17.18. //⼀般函数19. void Show ()20. {21. cout<<a<<endl;22. }23. };24.25. int main()26. {27. CExample A(100);28. CExample B = A; // CExample B(A); 也是⼀样的29. B.Show ();30. return 0;31. }CExample(const CExample& C) 就是我们⾃定义的拷贝构造函数。

拷贝构造和拷贝赋值

拷贝构造和拷贝赋值

拷贝构造和拷贝赋值拷贝构造和拷贝赋值是面向对象编程中常用的两个概念。

它们在C++、Java等编程语言中经常被用到,对于理解对象的复制和拷贝有着重要的作用。

拷贝构造是指通过已存在的对象创建一个新的对象,这个新对象和原对象的成员变量具有相同的值。

例如,我们有一个学生类(Student),其中包含学生的姓名、学号、年龄等成员变量。

当我们通过已存在的学生对象创建一个新的学生对象时,就需要使用拷贝构造。

拷贝构造函数在C++中常用的格式为:类名(const 类名& obj)。

在拷贝构造函数中,我们将传递进来的对象的成员变量值赋值给新创建的对象的成员变量。

拷贝构造函数的使用可以大大简化对象的创建过程,并且保证了新创建的对象和原对象之间的数据一致性。

同时,拷贝构造函数还可以用于对象作为函数参数进行传递,以及对象作为函数返回值返回的情况。

拷贝赋值是指将一个已存在的对象的值赋给另一个已经存在的对象。

在C++中,我们可以通过重载赋值操作符(=)来实现对象的拷贝赋值。

拷贝赋值的格式为:类名& operator=(const 类名& obj)。

在拷贝赋值中,我们将被赋值对象的成员变量值赋给目标对象的成员变量。

拷贝赋值操作符的使用可以方便地将一个对象的值拷贝给另一个对象,使得两个对象具有相同的值。

拷贝赋值操作符还可以用于链式赋值,即多个赋值操作符连续使用的情况。

无论是拷贝构造还是拷贝赋值,都是对象间的复制操作,但它们的触发时机和方式是不同的。

拷贝构造是在创建新对象时调用,而拷贝赋值是在已有对象进行赋值操作时调用。

需要注意的是,在使用拷贝构造和拷贝赋值的过程中,我们需要自行管理动态分配的资源(如堆内存),防止内存泄漏和悬垂指针的问题。

拷贝构造和拷贝赋值在实际的编程中有着广泛的应用。

它们不仅可以用于类的对象,还可以用于容器类、智能指针等等。

对于理解对象的复制、赋值和传递过程,以及保证程序的正确性和高效性,拷贝构造和拷贝赋值具有重要的指导意义。

C++中拷贝构造函数与赋值运算符使用

C++中拷贝构造函数与赋值运算符使用
通常情况下的简单对象 ,不使用额外系统资源 ,则无须 提供默认拷贝构造函数或默认赋值运算符. 但是 ,如果对象 使用 了系 统资 源 ,就必 须为类提 供拷贝 构造函 数和赋值 运 算符 ,否则会引起如下错误 :
(1) 资源重用 ,任 何一方的 变化都 会影 响另一 方 ,造成 结果错误 ,资源的归属权不清 .
char name [ 20] ;} ; class base2
{public : base2( char 3 pn =“noname”,int x = 0) :obj (pn) { num = x ; cou〈t〈“constructing2 = ”< <“ ”< < num < < endl ;} pro tect ed :
第 22 卷 第 2 期 2006 年 4 月
赤 峰学 院 学报 Journal of Chifeng College
Vol. 22 No. 2 Apr. 2006
C+ +中拷贝构造函数与赋值运算符使用
刘 燕
(赤峰学院 计算机科学与技术系 ,内蒙古 赤峰 024000)
摘 要 : , 在使用过程中非常容
int num ; basel obj ;} ; void main( ) { base2 obj21(“Randy”,12345) ; base2 obj22 = obj21 ;/ / 调用拷贝构造函数 base2 obj23 ; obj23 = obj21 ;}/ / 调用赋值运算符 2. 1 例 1 中 base1 类和 base2 类均没有 提供拷贝 构造函数 和赋值 运 算 符 ,运 行 程 序 会 得 到 正 确 的 结 果 . 构 造 对 象 obj22 时 ,系统先调用 类成 员的 默认拷 贝构造 函数 ,完 成类 成员的拷贝工作 ,然后 再调 用组 合类 的默 认拷 贝构 造函 数 , 完成其它成员的拷贝 工作 . 对象 obj23 被赋值时 ,两 个类均 调用了默认赋值运算符 . 2.2 若在例 1 中只为 base1 类提 供拷 贝构 造函 数和赋值运 算符如下 : base 1 ( base 1 &s) { strcpy(name ,s. name) ; cout < <“copy constructingl”< < name < < endl ;} base 1 &operator = (base 1 &s) { strcpy( name ,s. name) ; cout < <“operator = ”< < name < < endl ; return 3 this;

C++拷贝构造函数和赋值构造函数

C++拷贝构造函数和赋值构造函数

C++拷贝构造函数和赋值构造函数转⾃:⼀、拷贝构造函数int main(int argc, char * argv[]){CExample A;A.Init40);CExample B=A; //把B初始化为A的副本...}B = A ; 此语句的具体过程:⾸先建⽴对象theObjtwo,并调⽤其构造函数,然后成员被拷贝。

语句"CExample B=A;" ⽤ A 初始化 B。

其完成⽅式是内存拷贝,复制所有成员的值。

完成后,A.pBuffer = B.pBuffer, 即它们将指向同样的地⽅,指针虽然复制了,但所指向的空间并没有复制,⽽是由两个对象共⽤了。

这样不符合要求,对象之间不独⽴了,并为空间的删除带来隐患。

所以需要采⽤必要的⼿段(拷贝构造函数)来避免此类情况。

拷贝构造函数的格式为 : 构造函数名(对象的引⽤) 提供了拷贝构造函数后的CExample类定义为:class CExample{public :CExample(){pBuffer=NULL; nSize=0;} //构造函数~CExample(){delete pBuffer;} // 析构函数CExample(const CExample&); //拷贝构造函数void Init(int n){ pBuffer=new char [n]; nSize=n;}private :char *pBuffer; //类的对象中包含指针,指向动态分配的内存资源int nSize;};//拷贝构造函数的定义CExample::CExample(const CExample& RightSides){nSize=RightSides.nSize; //复制常规成员pBuffer=new char [nSize]; //复制指针指向的内容memcpy(pBuffer,RightSides.pBuffer,nSize*sizeof (char ));}这样,定义新对象,并⽤已有对象初始化新对象时,即执⾏语句“CExample B=A; ” 时,CExample(const CExample& RightSides)将被调⽤,⽽已有对象⽤别名RightSides传给构造函数,以⽤来作复制。

拷贝构造函数和赋值函数

拷贝构造函数和赋值函数

拷贝构造函数和赋值函数拷贝构造函数和赋值函数是C++中两个重要的函数,它们都是用来复制对象的。

拷贝构造函数用于创建一个新对象并将其初始化为另一个对象的副本,而赋值函数则用于将一个对象的值赋给另一个对象。

在本文中,我们将详细讨论这两个函数的作用和使用方法。

一、拷贝构造函数拷贝构造函数是一个特殊的构造函数,它用于创建一个新对象并将其初始化为另一个对象的副本。

当我们使用一个对象来初始化另一个对象时,拷贝构造函数就会被调用。

例如:```class MyClass {public:MyClass(); // 默认构造函数MyClass(const MyClass& other); // 拷贝构造函数// ...};MyClass obj1; // 调用默认构造函数MyClass obj2(obj1); // 调用拷贝构造函数```在上面的代码中,当我们使用obj1来初始化obj2时,拷贝构造函数就会被调用。

拷贝构造函数的参数是一个常量引用,它表示要复制的对象。

在拷贝构造函数中,我们可以使用另一个对象的数据来初始化新对象的数据成员,从而创建一个新的对象。

需要注意的是,如果我们没有定义拷贝构造函数,编译器会自动生成一个默认的拷贝构造函数。

这个默认的拷贝构造函数会将一个对象的数据成员逐个复制到另一个对象中。

但是,如果我们的类中有指针类型的数据成员,那么默认的拷贝构造函数可能会出现问题,因为它只是简单地复制指针的值,而不是复制指针所指向的对象。

这时,我们就需要自己定义拷贝构造函数来保证正确的复制。

二、赋值函数赋值函数是用于将一个对象的值赋给另一个对象的函数。

当我们使用一个对象来赋值给另一个对象时,赋值函数就会被调用。

例如:```class MyClass {public:MyClass& operator=(const MyClass& other); // 赋值函数// ...};MyClass obj1, obj2;obj2 = obj1; // 调用赋值函数```在上面的代码中,当我们将obj1赋值给obj2时,赋值函数就会被调用。

【C++Primer第15章】定义派生类拷贝构造函数、赋值运算符

【C++Primer第15章】定义派生类拷贝构造函数、赋值运算符

【C++Primer第15章】定义派⽣类拷贝构造函数、赋值运算符学习资料••定义拷贝构造函数【注意】对派⽣类进⾏拷贝构造时,如果想让基类的成员也同时拷贝,就⼀定要在派⽣类拷贝构造函数初始化列表中显⽰调⽤基类拷贝构造函数(当然在函数体内将基类部分的值拷贝也是可以的,只不过它是先⽤默认构造函数初始化后再修改的基类成员变量的值,效率⽐较低),否则它会调⽤基类的默认构造函数,⽽不会对基类的成员变量拷贝值,这样⽣成的对象,它的派⽣类部分和被拷贝的对象派⽣类部分⼀样,⽽基类部分则是默认构造函数的初始化结果。

代码例⼦1:1 #include <iostream>2using namespace std;34class A5 {6public:7 A() { cout << "A default constructor" << endl; }8 A(A&) { cout << "A copy constructor" << endl; }9 };10class B : public A11 {12public:13 B() { cout << "A default constructor" << endl; }14 B(B &b) { cout << "B copy constructor" << endl; }15 };1617int main()18 {19 B b;20 B c = b;21return0;22 }输出结果:代码例⼦2:1 #include <iostream>2using namespace std;34class A5 {6public:7 A() { cout << "A default constructor" << endl; }8 A(A&) { cout << "A copy constructor" << endl; }9 };10class B : public A11 {12public:13 B() { cout << "A default constructor" << endl; }14 B(B &b) : A(b) { cout << "B copy constructor" << endl; }15 };1619 B b;20 B c = b;21return0;22 }输出结果:C++ 基类构造函数带参数的继承⽅式及派⽣类的初始化在定义类的时候,会遇到基类的构造函数带参数,⽽⼦类⼦类构造函数不带参数,这时候如果以代码 a 的⽅式建⽴派⽣类则会出错。

C++类构造函数、拷贝构造函数、复制构造函数、复制构造函数、构造函数显示调用和隐式调用

C++类构造函数、拷贝构造函数、复制构造函数、复制构造函数、构造函数显示调用和隐式调用

C++类构造函数、拷贝构造函数、复制构造函数、复制构造函数、构造函数显⽰调⽤和隐式调⽤⼀、构造函数是⼲什么的1.class Counter2.{3.public:4.// 类Counter的构造函数5.// 特点:以类名作为函数名,⽆返回类型6.Counter()7.{8.m_value = 0;9.}10.private:11.// 数据成员12.int m_value;13.}该类对象被创建时,编译系统对象分配内存空间,并⾃动调⽤该构造函数->由构造函数完成成员的初始化⼯作eg: Counter c1;编译系统为对象c1的每个数据成员(m_value)分配内存空间,并调⽤构造函数Counter( )⾃动地初始化对象c1的m_value值设置为0故:构造函数的作⽤:初始化对象的数据成员。

⼆、构造函数的种类1.class Complex2.{3.private :4.double m_real;5.double m_imag;6.public:7.Complex() //⼀般构造函数8.{9.m_real = 0.0;10.m_imag = 0.0;11.}12.13.Complex(double real, double imag) //⼀般构造函数14.{15.m_real = real;16.m_imag = imag;17.}18.19.Complex(const Complex & c) //拷贝构造函数20.{21.// 将对象c中的数据成员值复制过来22.m_real = c.m_real;23.m_imag = c.m_imag;24.}25.Complex &operator=( const Complex &rhs ) //赋值构造函数26.{27.// ⾸先检测等号右边的是否就是左边的对象本⾝,若是本对象本⾝,则直接返回28.if ( this == &rhs )29.{30.return *this;31.}32.// 复制等号右边的成员到左边的对象中33.this->m_real = rhs.m_real;34.this->m_imag = rhs.m_imag;35.// 把等号左边的对象再次传出36.return *this;37.}38.};// ⽆参数构造函数// 如果创建⼀个类你没有写任何构造函数,则系统会⾃动⽣成默认的⽆参构造函数,函数为空,什么都不做// 只要你写了⼀个下⾯的某⼀种构造函数,系统就不会再⾃动⽣成这样⼀个默认的构造函数,如果希望有⼀个这样的⽆参构造函数,则需要⾃⼰显⽰地写出来// ⼀般构造函数(也称重载构造函数)// ⼀般构造函数可以有各种参数形式,⼀个类可以有多个⼀般构造函数,前提是参数的个数或者类型不同(基于c++的重载函数原理) // 例如:你还可以写⼀个 Complex( int num)的构造函数出来// 创建对象时根据传⼊的参数不同调⽤不同的构造函数// 复制构造函数(也称为拷贝构造函数)// 复制构造函数参数为类对象本⾝的引⽤,⽤于根据⼀个已存在的对象复制出⼀个新的该类的对象,⼀般在函数中会将已存在对象的数据成员的值复制⼀份到新创建的对象中// 若没有显⽰的写复制构造函数,则系统会默认创建⼀个复制构造函数,但当类中有指针成员时,由系统默认创建该复制构造函数会存在风险,具体原因请查询有关 “浅拷贝” 、“深拷贝”的⽂章论述// 类型转换构造函数,根据⼀个指定的类型的对象创建⼀个本类的对象,//需要注意的⼀点是,这个其实就是⼀般的构造函数,但是对于出现这种单参数的构造函数,C++会默认将参数对应的类型转换为该类类型,有时候这种隐私的转换是我们所不想要的,所以需要使⽤explicit来限制这种转换。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档