C++构造函数、复制构造函数和析构函数专题(修订版)

合集下载

含有指针变量的类需要重写拷贝构造函数,拷贝赋值函数,析构函数

含有指针变量的类需要重写拷贝构造函数,拷贝赋值函数,析构函数

含有指针变量的类需要重写拷贝构造函数,拷贝赋值函数,析构函数编译器⾃带拷贝构造(ctor)和拷贝赋值函数(operator =),但是对于成员变量含有指针的类,其不能使⽤默认的拷贝赋值函数。

因为使⽤默认的,会直接将指针指向的地址进⾏赋值 (浅拷贝,共享内存,共指⼀个对象),⽽不是分配⼀块内存,具有相同的数值 (深拷贝,独⽴,两个对象)。

浅拷贝容易造成dangling pointer。

⽤⼀个例⼦来展⽰:1 #ifndef __MYSTRING__2#define __MYSTRING__34class String{5public:6 String(const char* cstr=0);7 String(const String& str); // 拷贝构造8 String& operator= (const String& str); // 拷贝赋值9 ~String();10char* get_c_str const(){11return m_data;12 }13private:14char* m_data; // 带指针成员的类:⼀定要注意拷贝赋值,拷贝构造,析构15// String的底部通过char实现,在外部表现为string16 };1718 inline String::String ( const char* cstr=0 ){19if(cstr){20 m_data=new char[strlen(cstr)+1];21 strcpy(m_data,cstr); // char * strcpy ( char * destination, const char * source );22 }23else{ // 考虑cstr=0;24 m_data=new char[1];25 m_data[0]='\0';26 }27 }2829 inline String::String(const String& str){30 m_data=new char[strlen(str.get_c_str())+1];31 strcpy(m_data,str.m_data);32 }3334 inline String::~String(){35delete[] m_data;36 }3738 inline String& String::operator=(const String& str){39if(this==&str){ // self assignment :⾃我检验(如果没有进⾏这样的处理,在⾃我赋值会产⽣严重的错误)40return *this;41 }42// 构造函数是第⼀次,因此不需要删除,但是赋值需要先进⾏delete43delete[] m_data; // 先删除,重新分配⼀样⼤⼩!44 m_data=new char[strlen(str.get_c_str())+1];45 strcpy(m_data,str.m_data);46return *this; // 其实不⽤返回*this也可以,因为已经实现了修改,但是这样有⼀个好处可以实现 a=b=c;(因为返回的类型继续⽀持=)47 }4849// 调⽤形式: cout << String() ; 第⼀个参数为 << 左边,第⼆个参数为 << 右侧;返回ostream 可以实现 cout << a << b ;50 ostream& operator<<(ostream& os,const String& str){51 os<<str.get_c_str();52return os;53 }5455#endif。

详解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++_构造函数与析构函数构造函数与析构函数1 构造函数1.1 构造函数具有⼀些特殊的性质1.2 定义构造函数的⼀般形式1.3 利⽤构造函数创建对象2 成员初始化表3 缺省参数的构造函数4 重载构造函数5 拷贝构造函数5.1 ⾃定义拷贝构造函数5.2 缺省的拷贝构造函数5.3 调⽤拷贝构造函数的三种情况5.4 浅拷贝和深拷贝6 析构函数7 调⽤构造函数和析构函数的顺序8 对象的⽣存期构造函数和析构函数都是类的成员函数,但它们都是特殊的成员函数,执⾏特殊的功能,不⽤调⽤便⾃动执⾏,⽽且这些函数的名字与类的名字有关。

C++语⾔中有⼀些成员函数性质是特殊的,这些成员函数负责对象的建⽴、删除。

这些函数的特殊性在于可以由编译器⾃动地隐含调⽤,其中⼀些函数调⽤格式采⽤运算符函数重载的语法。

C++引进⼀个⾃动完成对象初始化过程的机制,这就是类的构造函数。

对象的初始化1. 数据成员是不能在声明类时初始化2. 类型对象的初始化⽅法:1. 调⽤对外接⼝(public成员函数)实现:声明类→定义对象→调⽤接⼝给成员赋值2. 应⽤构造函数(constructor)实现:声明类→定义对象→同时给成员赋值1. 构造函数构造函数是⼀种特殊的成员函数,它主要⽤于为对象分配空间,进⾏初始化。

1.1 构造函数具有⼀些特殊的性质:(1) 构造函数的名字必须与类名相同。

(2) 构造函数可以有任意类型的参数,但不能指定返回类型。

它有隐含的返回值,该值由系统内部使⽤。

(3) 构造函数是特殊的成员函数,函数体可写在类体内,也可写在类体外。

(4) 构造函数可以重载,即⼀个类中可以定义多个参数个数或参数类型不同的构造函数。

构造函数是不能继承(5) 构造函数被声明为公有函数,但它不能像其他成员函数那样被显式地调⽤,它是在定义对象的同时被调⽤的。

(6) 在声明类时如果没有定义类的构造函数,编译系统就会在编译时⾃动⽣成⼀个默认形式的构造函数,(7) 默认构造函数是构造对象时不提供参数的构造函数。

C++试题(含答案)

C++试题(含答案)

C++试题(含答案)一、选择题1、下列的各类函数中,不是类的成员函数()。

A) 构造函数B) 析构函数C) 友元函数D) 拷贝初始化构造函数2、已知: int n=10;下列表示引用的方法中,正确的是()。

A) int &r;B) int &r=10;C) int &r=n;D) int *r=&n;3、下列关于析构函数的说法,正确的是()A) 其名与类名完全相同B) 返回类型是void类型C) 函数体中必须有delete语句D) 无形参,不可重载4、已知函数原型:void fun(int a,int b=7,char z='*'); 则下面函数调用中不合法的为()。

A) fun(5); B) fun(5,8); C) fun(5,'#'); D) fun(0,0,'*');;5、类A是类B的友元,类B是类C的友元,则以下说法正确的是()。

A) 类B是类A的友元B) 类C是类A的友元C) 类A是类C的友元D) 以上都不对6、关于对象成员的构造函数的调用顺序,说法正确的是()。

A)与它们在类中说明顺序相同B)与析构函数的调用顺序相同C)与它们在成员初始化列表中给出的顺序相同D)以上说法都不对7、以下关于内联函数的说法正确的是()A)类的内联函数必须在类体外用关键字inline定义B)类的内联函数必须在类体内定义C)编译时将内联函数的目标代码插入每个调用该函数的地方D)运行时将内联函数的目标代码插入每个调用该函数的地方8、在有同名全局变量和局部变量时,可以用()提供对全局变量的访问。

A)类运算符B)域运算符C)重载D)引用9、假定x为一个类,执行X a[3],*p[2];语句时会自动调用该类的构造函数()次。

A)2 B)3 C)4 D)510、下列关于new运算符的描述中,错误的是( )。

A) 可以new运算符来动态创建对象和对象数组B) 使用new运算符创建的对象或对象数组,可以使用运算符delete删除C) 使用new运算符创建对象时要调用构造函数D) 使用new运算符调用对象数组时不允许指定初始值11、下面对静态数据成员的描述中,正确的是()A)类的每个对象都有自己的静态数据成员B)静态数据成员是类的所有对象共享的数据C)类的不同对象有不同的静态数据成员值D)静态数据成员不能通过类的对象调用12、如果一个类至少有一个纯虚函数,那么就称该类为()。

C++在单继承、多继承、虚继承时,构造函数、复制构造函数、赋值操作符、析构函数的执行顺序和执行内容

C++在单继承、多继承、虚继承时,构造函数、复制构造函数、赋值操作符、析构函数的执行顺序和执行内容

C++在单继承、多继承、虚继承时,构造函数、复制构造函数、赋值操作符、析构函数的执⾏顺序和执⾏内容⼀、本⽂⽬的与说明1. 本⽂⽬的:理清在各种继承时,构造函数、复制构造函数、赋值操作符、析构函数的执⾏顺序和执⾏内容。

2. 说明:虽然复制构造函数属于构造函数的⼀种,有共同的地⽅,但是也具有⼀定的特殊性,所以在总结它的性质时将它单独列出来了。

3. 单继承、多继承、虚继承,既然都属于继承,那么虽然有⼀定的区别,但还是相同点⽐较多。

如果放在⼀块讲,但为了将内容制作成递进的,就分开了,对相同点进⾏重复,(⼤量的复制粘贴哈),但在不同点进⾏了标注。

注意:三块内容是逐步递进的如果你懂虚函数,那么单继承和多继承那块你就可以不看;如果你懂多继承,那单继承你就不要看了,⾄于虚继承就等你懂虚继承再回来看吧;如果你只懂单继承,那你就只看单继承就好。

⼆、基本知识1. 对于⼀个空类,例如:class EmptyClass{};虽然你没有声明任何函数,但是编译器会⾃动为你提供上⾯这四个⽅法。

class EmptyClass {public:EmptyClass(); // 默认构造函数EmptyClass(const EmptyClass &rhs); // 复制构造函数~EmptyClass(); // 析构函数EmptyClass& operator=(const EmptyClass &rhs); // 赋值运算符}对于这四个⽅法的任何⼀个,你的类如果没有声明,那么编译器就会⾃动为你对应的提供⼀个默认的(注意合成默认构造函数是⽤于没有编写构造函数编译器才会合成默认构造函数,其中复制构造函数也是构造函数)。

(在《C++ primer》中,这个编译器⾃动提供的版本叫做“合成的***”,例如合成的复制构造函数)当然如果你显式声明了,编译器就不会再提供相应的⽅法。

2. 合成的默认构造函数执⾏内容:如果有⽗类,就先调⽤⽗类的默认构造函数。

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) 就是我们⾃定义的拷贝构造函数。

构造、复制、析构语意学

构造、复制、析构语意学

1.调用所有虚基类的构造函数,从左到右,从最深到最浅:o如果该类被列于成员初始化列表中,任何明确明确指定的参数,都应该被传递过来。

若没有列入成员初始化列表中,虚基类的一个默认构造函数被调用(有的话)。

o此外,要保证虚基类的偏移量在执行期可存取,对于使用vbptr来实现虚基类的编译器来说,满足这点要求就是对vbptr的初始化。

o然而,只有在类对象代表着“most-derived class”时,这些构造函数才可能会被调用。

一些支持这个行为的代码会被放进去2(直观点说就是,虚基类的构造由最外层类控制)。

2.调用所有基类构造函数,依声明顺序:o如果该基类被列入了成员初始化队列,那么所有明确指定的参数,应该被传递过来。

o没有列入的话,那么调用其默认构造函数,如果有的话。

o如果该基类是第二顺位或之后的基类,this 指针必须被调整。

3.正确初始化vptr,如果有的话。

4.调用没有出现在初始化成员列表中的member object的默认构造函数,如果有的话。

5.记录在成员初始化队列中的数据成员初始化操作以声明的顺序被放进构造函数中。

∙什么都不做,采用编译器提供默认行为(bitwise copy或者由编译器合成一个)。

∙自己提供一个赋值运算符操作。

∙明确拒绝将一个对象指定给另一个对象。

对于第三点,只要将赋值操作符声明为private,且不定义它就可以了。

对于第二点,只有在第一点的行为不安全或不正确,或你特别想往其中插入点东西的时候。

以下四种情况copy assignment operator(还是用它的英文名,感觉顺畅点),不具有bitwise copy语意,也就是说这些情况下,编译器要合成copy assignment operator 而不能依靠bitwise copy来完成赋值操作,这四种情况与构造函数、拷贝构造函数的情况类似,原因可以参考它们的。

四种情况如下:∙类包含有定义了copy assignment operator的class object成员。

C语言里面构造函数和析构函数的运用办法

C语言里面构造函数和析构函数的运用办法

C语言里面构造函数和析构函数的运用办法C语言里面构造函数和析构函数的运用办法摘要:构造函数与析构函数是一个类中看似较为简单的两类函数,但在实际运用过程中总会出现一些意想不到的运行错误。

本文将较系统的介绍构造函数与析构函数的原理及在C#中的运用,以及在使用过程中需要注意的若干事项。

关键字:构造函数;析构函数;垃圾回收器;非托管资源;托管资源一.构造函数与析构函数的原理作为比C更先进的语言,C#提供了更好的机制来增强程序的安全性。

C#编译器具有严格的类型安全检查功能,它几乎能找出程序中所有的语法问题,这的确帮了程序员的大忙。

但是程序通过了编译检查并不表示错误已经不存在了,在“错误”的大家庭里,“语法错误”的地位只能算是冰山一角。

级别高的错误通常隐藏得很深,不容易发现。

根据经验,不少难以察觉的程序错误是由于变量没有被正确初始化或清除造成的,而初始化和清除工作很容易被人遗忘。

微软利用面向对象的概念在设计C#语言时充分考虑了这个问题并很好地予以解决:把对象的初始化工作放在构造函数中,把清除工作放在析构函数中。

当对象被创建时,构造函数被自动执行。

当对象消亡时,析构函数被自动执行。

这样就不用担心忘记对象的初始化和清除工作。

二.构造函数在C#中的运用构造函数的名字不能随便起,必须让编译器认得出才可以被自动执行。

它的命名方法既简单又合理:让构造函数与类同名。

除了名字外,构造函数的另一个特别之处是没有返回值类型,这与返回值类型为void的函数不同。

如果它有返回值类型,那么编译器将不知所措。

在你可以访问一个类的方法、属性或任何其它东西之前,第一条执行的语句是包含有相应类的构造函数。

甚至你自己不写一个构造函数,也会有一个缺省构造函数提供给你。

class TestClass{public TestClass(): base() {} // 由CLR提供}下面列举了几种类型的构造函数1)缺省构造函数class TestClass{public TestClass(): base() {}}上面已介绍,它由系统(CLR)提供。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
本文作者:黄邦勇帅(编著)(原名:黄勇) 本文是学习 C++中的最基本的内容,因此学习 C++就应全部掌握本文的内容。在知道了怎样声明一个类之后,就会遇 到关于构造函数的问题,本文是关于构造函数的专题,介绍了构造函数,重点讲解了成员初始化列表和析构函数,并 对复制构造函数、直接初始化、复制初始化、赋值、临时对象之间的关系作了深入讲解,本文内容全面,简单易懂。 本文使用的是 x86 机器(主流计算机都是 x86 机器),windows xp 操作系统,VC++2005 编译器进行讲解的。 本文内容完全属于个人见解与参考文现的作者无关,限于水平有限,其中难免有误解之处,望指出更正。 声明:禁止抄袭,复印,转载本文,本文作者拥有完全版权。 主要参考文献: 1、C++.Primer.Plus.第五版.中文版 [美]Stephen Prata 著 孙建春 韦强译 人民邮电出版社 2005 年 5 月 2、C++.Primer.Plus.第四版.中文版 Stanley B.Lippman、Barbara E.Moo 著 李师贤等译 人民邮电出版社 2006 年 3 月 3、C++.Primer.Plus.第三版.中文版 Stanley B.Lippman 等著 潘爱民 张丽译 中国电力出版社 2002 年 5 月 4、 《高质量 C++编程指南》 作者 林锐 出版社不详 2001 年 7 月 5、 《C++程序设计》 作者 谭浩强 清华大学出版社 2004 年 6 月
示例:构造函数和Biblioteka 认构造函数#include <iostream> #include <string> using namespace std; class A{public: //void A(){} //A()const{} //A1(){} A(){cout<<"A"<<endl;} A(int i){cout<<"Ai"<<endl;} }; //构造函数一般被声明为公有的,因为主要是用来初始化对象的数据成员的 //错误,构造函数不能反回任何值(包括void类型) //错误,构造函数不能是const或volatile的 //错误,构造函数的名称必须与类名相同。 //正确,构造函数可以有形参也可以没有形参 //正确,可以重载多个构造函数的版本
//这是默认构造函数 //错误,这也是默认构造函数,因为默认构造函数只能有一个。默认构造函数是不需要实参就能被调 用的构造函数,因此所有的形参都有默认值的构造函数也是默认构造函数
void main(){ //只要创建对象就会自动执行一个构造函数,或调用构造函数就会创建一个对象 A ma; //调用构造函数A()创建对象。 A ma1(3); //调用构造函数A(int)创建对象 A1 ma2; //使用A1自动提供的默认构造函数创建对象。 //A2 ma3; //错误,因为类A2自定义了构造函数,且没有自定义默认构造函数,所以系统不会自动产生默认构造函数,因此对象ma3 没有合适的构造函数可调用。 //ma.A(); //错误,不能用类的对象来直接调用构造函数 A(3); } //构造函数不能被类的对象直接调用,但并不是不能被直接调用,这里表示直接调用A的构造函数A(int)创建一个临时对 象,然后临时对象被撤消
class A1{}; class A2{public: A2(int i,int j){} }; class A3{ public: A3(){} //A3(int i=2,int j=3){} };
//A1使用默认构造函数。如果没有提供任何构造函数,则C++会提供一个默认构造函数
//若用户自已定义了任何一个构造函数C++就不会自动生成默认构造函数,如果这时用户自已也没提供 默认构造函数,则此类就没有默认构造函数
class A2{public: //explicit void f(){} //错误,explicit关键字只能作用于构造函数的声明上 explicit A2(int i){cout<<"A2"<<endl;}}; //explicit关键字可以禁止单形参构造函数的 隐式转换 。详见main函数中的调用。 class A3{public: A3(int i); }; //explicit A3::A3(int i){} //错误,在类外定义构造函数时不需要指定explicit关键字,也不能指定explicit关键字 void f1(A1 ma1,int i){cout<<"345<<endl;} void f2(A2 ma2){cout<<"675<<endl;} void main(){ A1 ma1=3; //正确,在未使用explicit关键字时,此方法与A1 ma1(3)等同。 //A2 ma2=3; //错误,单形参构造函数被explicit限制,此时只能使用A2 ma2(3);的形式调用该单形参构造函数创建对象。 //单形参构造函数的 隐式转换规则:在需要使用该类类型对象的地方,就会将该构造函数形参所示的类型转换为该类类型,在转换的过程 中可能会生成不必要的临时对象。 f1(3,1); //正确,对于单形参构造函数 在需要类类型A1的地方(f1函数的形参),会把构造函数的形参类型int隐式转换为A1类型, 这时会把int型的,转换为函数f1所需要的类型A1,其间会产生一个临时对象 f1(3.3,1); //正确,原理同f1(3),只是其间多了一个.3到的转换过程。 //f2(3); //错误,因为单形参构造函数被explicit所限制。 }
若出现此种错误时会很难发现。因此应避免出现这种转换。 4、限制单形参构造函数的隐式转换:将构造函数 声明为explicit 的就可 以禁止这种隐式转换,explicit 关键字只能作用 于构造函数的 声明上 , 在类 外定义构造函数时不需要指定 explicit 关键字, 也不能指定该关 键字。 比如 class A{public: explicit A(int i);}; explicit A::A(int i){} 错误,在类 外定义构造函数时无需指定 explicit 关键字。再如 class A{public: A(int i);}; explicit A::A(){}也是错误的,explicit 只能用于构造函数的 声明上 ,在类 外定义时是不能使用的。 5、可以像初始化普通变量的方式来调用单形参构造函数,比如 class A{public: A(int i){} }; A ma=3; 在单形参构造函 数未被 explicit 限制时,语句 A ma=3;与 A ma(3)是等价的。注意,若单形参构造函数被 explicit 限制,则不能使用 此方法创建对象。 6、未避免不必要的转换 和临时对象的产生,一般情况下单形参构造函数都应使用 explicit 进行 限制。
二、默认构造函数
1、默认构造函数是不需要实参就能被调用的构造函数,因此没有任何参数的构造函数是默认构造函数,所有的形参都 有默认值的构造函数也是默认构造函数。比如 class A{ public : A(){}}; 其中的 A()是默认构造函数,再如 class B{public: B(int i=1, int j=2){}}; 其中 B(int i, int j)也是默认构造函数。 2、如果没有提供任何构造函数,则 C++会提供一个默认构造函数,如果用户自已定义了任何一个构造函数C++就不自 动生成默认构造函数,如果这时用户自已也没提供默认构造函数,则此类就没有默认构造函数。比如 class A{}; A
第 9 部分 C++构造函数、复制构造函数和析构函数专题
(2014-10-17 修订完整版) (共 2 章 共 15 页)
第 1 章 构造函数简介与析构函数(共 6 页)
1.1 构造函数、默认构造函数、单形参构造函数、explicit 关键字
一、构造函数简介
1、构造函数的形式为:class A{ A(形参 1,形参 2…){ … } }; 其中,类体中的函数为构造函数。 2、构造函数的主要作用是用于初始化对象的数据成员。 3、构造函数就是一个函数,只不过他是类的一个特殊的成员函数。因此函数体中可以是任何内容。 4、构造函数的名称必须与类名相同。 5、构造函数不能反回任何值,也就是说不能为构造函数指定反回类型(包括 void 类型)。比如:class A{ public: void A(){}};是错误的,构造函数不能有反回类型即使是 void 也是不行的。 6、构造函数可以有形参也可以没有形参,也可以重载多个构造函数的版本。函数重载请参阅相关章节。 7、构造函数不能是 const 或 volatile 的,比如:class A{public: A() const; A(int i) volatile; }; 是错误的。 8、自动提供的默认构造函数的产生:若没有定义任何构造函数,则 C++会自动生成一个默认构造函数。 9、 只要创建对象就会自动执行一个构造函数, 且只执行一次, 反过来理解就是调用构造函数就会创建一个对象。 比如: class A{public: A(){}; } void main(){ A(); } 在 main 函数中表示使用默认构造函数创建一个对象, 不过这个对象没 有名字。 10、不能用类的对象来直接调用构造函数,但并不代表构造函数不可被显示调用。比如 class A{public: A(){} }; A ma; 则 ma.A();是错误的,但 A::A(),A(),ma.A::A()都是正确的。 11、构造函数一般都是公有的,因为构造函数一般是用来初始化对象的数据成员的。 12、使用构造函数初始化对象的方法,请参阅下一章。
示例:单形参构造函数与explicit关键字
相关文档
最新文档