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)提供。

c++ 构造函数复制构造函数

c++ 构造函数复制构造函数

c++ 构造函数复制构造函数C++构造函数和复制构造函数是面向对象编程中重要的概念。

构造函数是在创建对象时自动调用的函数,用于初始化对象的成员变量。

复制构造函数则是在对象复制时自动调用的函数,用于将一个对象的值复制到另一个对象中。

本文将介绍 C++ 构造函数和复制构造函数的概念、用法和注意事项。

1. 构造函数构造函数是一种特殊的成员函数,用于初始化对象的成员变量。

构造函数的名称必须与类名相同,没有返回值,也不需要显式调用。

当创建对象时,系统会自动调用该类的构造函数进行对象的初始化。

例如:```class MyClass {public:MyClass() {// 构造函数代码}};```在上面的示例中,定义了一个名为 MyClass 的类,该类包含一个构造函数。

当创建 MyClass 对象时,该构造函数将被自动调用进行对象的初始化。

在 C++ 中,构造函数可以有多个重载版本。

例如,可以定义一个带参数的构造函数:```class MyClass {public:MyClass(int value) {// 构造函数代码}};```在上面的示例中,定义了一个带一个整型参数的 MyClass 构造函数。

当使用 MyClass(int value) 创建对象时,该构造函数将被自动调用进行对象的初始化。

2. 复制构造函数复制构造函数是一种特殊的构造函数,用于将一个对象的值复制到另一个对象中。

当使用一个对象创建另一个对象时,系统会自动调用该类的复制构造函数进行对象的复制。

例如:```class MyClass {public:MyClass(const MyClass& other) {// 复制构造函数代码}};```在上面的示例中,定义了一个名为 MyClass 的类,该类包含一个复制构造函数。

当使用一个 MyClass 对象创建另一个 MyClass 对象时,该复制构造函数将被自动调用进行对象的复制。

c++程序设计教程 第十章 构造函数和析构函数

c++程序设计教程 第十章 构造函数和析构函数

10.1.2 构造函数重载
在一个类中可以定义多个构造函数,以便对类 对象提供不同的初始化方法。这些构造函数的函数 名完全相同,都没有返回值,而参数的类型或参数 的个数各不相同。对于一般的重载函数,系统是根 据参数列表来决定调用哪个函数,对重载的构造函 数而言,系统是根据创建对象时提供的参数来确定 调用哪个构造函数来初始化对象的。
return s;
4
}
2.使用参数初始化列表的构造函数
使用参数初始化列表的构造函数的形式为:
类名::构造函数名(<形参1,形参2,……>)<:数据成员1(形参1),数据成员2(形参2 ),………>
{函数体} 例10.1 中定义类Tri 的构造函数可以写成如下形式:
Tri(double x , double y , double z ):a(x),b(y),c(z){}
return s;
cout<<"Tria的周长"<<Tria.Peri()<<endl;
}
cout<<"tria的面积为: "<<tria.Area()<<endl;
};
}
7
10.1.3 默认的构造函数
默认的构造函数又称缺省的构造函数,有两种形式:
(1)参数为缺省值的构造函数,如在类体中说明以下形式 的构造函数:
函数,并不是用函数名调用的,而是隐式调用的
2
定义构造函数的两种方法
构造函数有不带参数的和带参数的两种,其定义的 形式都是一致的。 1.在构造函数体内对数据成员赋值: 在类体中定义构造函数的形式如下: 类名(<形参1,形参2,……>) {函数体} 其中,尖括号< >中的内容可以省略。

c++ 构造函数与析构函数

c++ 构造函数与析构函数

• 只要一个类定义了一个构造函数(不一定 只要一个类定义了一个构造函数( 是无参构造函数), ),C++编译系统就不再 是无参构造函数), 编译系统就不再 提供默认的构造函数。 提供默认的构造函数。
析构函数
• 当一个对象被定义时,系统自动调用构造函数为 当一个对象被定义时, 该对象分配相应的资源,当对象使用完毕后, 该对象分配相应的资源,当对象使用完毕后,这 些系统资源需要在对象消失前被释放。 些系统资源需要在对象消失前被释放。 • 析构函数的定义方式为: 析构函数的定义方式为:
– 一个类中只能拥有一个析构函数。 一个类中只能拥有一个析构函数。 – 对于一个简单的类来说,大多可以直接使用系 对于一个简单的类来说, 统提供的默认析构函数。 统提供的默认析构函数。
• 但是,如果在类的对象中分配有动态内存(如:用 但是,如果在类的对象中分配有动态内存( new申请分配的内容)时,就必须为该类提供适当 申请分配的内容) 申请分果: 结果:
拷贝构造函数
• 拷贝构造函数
– 是C++中引入的一种新的构造函数。 中引入的一种新的构造函数。 中引入的一种新的构造函数 – 其作用是使用一个已经存在的对象(有拷贝构造函 其作用是使用一个已经存在的对象( 使用一个已经存在的对象 数的形参提供),去初始化一个新创建的对象 数的形参提供),去初始化一个新创建的对象 ),
• 例子: 类person包括 个数据成员,用来记录人员信 例子: 包括4个数据成员 包括 个数据成员, 生成对象obj,并使用构造函数为 息。生成对象 ,并使用构造函数为obj赋予初始值 赋予初始值
#include <iostream> class Person //定义类 { private: //类Person的数据成员 char name[10]; //姓名 int age; //年龄 int salary; //薪金 char tel[20]; //电话 public: //构造函数Person Person( char *xname, int xage, int xsalary, char *xtel); void disp (); };

C++试题及答案 (五)

C++试题及答案 (五)

C++程序设计模拟试卷(五)一、单项选择题(本大题共20小题,每小题1分,共20分)在每小题列出的四个备选项中只有一个是符合题目要求的,请将其代码填写在题后的括号内。

错选、多选或未选均无分。

1。

静态成员函数没有()A。

返回值B. this指针C. 指针参数D。

返回类型答案:B解析:静态成员函数是普通的函数前加入static,它具有函数的所有的特征:返回类型、形参,所以使用静态成员函数,指针可以作为形参,也具有返回值。

静态成员是类具有的属性,不是对象的特征,而this表示的是隐藏的对象的指针,因此静态成员函数没有this 指针。

静态成员函数当在类外定义时,要注意不能使用static关键字作为前缀.由于静态成员函数在类中只有一个拷贝(副本),因此它访问对象的成员时要受到一些限制:静态成员函数可以直接访问类中说明的静态成员,但不能直接访问类中说明的非静态成员;若要访问非静态成员时,必须通过参数传递的方式得到相应的对象,再通过对象来访问.2. 在类的定义中,用于为对象分配内存空间,对类的数据成员进行初始化并执行其他内部管理操作的函数是()A. 友元函数B。

虚函数C. 构造函数D. 析构函数答案:C解析:定义构造函数作用就是初始化对象,而析构函数释放对象空间。

虚函数用于完成多态性,友元增加访问方便性。

3。

所有在函数中定义的变量,都是()A. 全局变量B. 局部变量C。

静态变量D. 寄存器变量答案:B解析:变量存储类可分为两类:全局变量和局部变量.(1)全局变量:在函数外部定义的变量称为全局变量,其作用域为:从定义变量的位置开始到源程序结束。

全局变量增加了函数之间数据联系的渠道,全局变量作用域内的函数,均可使用、修改该全局变量的值,但是使用全局变量降低了程序的可理解性,软件工程学提倡尽量避免使用全局变量。

(2)局部变量:在函数内部定义的变量称为局部变量,其作用域为:从定义变量的位置开始到函数结束。

局部变量包含自动变量(auto)静态变量(static)以及函数参数.auto变量意味着变量的存储空间的分配与释放是自动进行的.说明符auto可以省略。

类、构造函数、析构函数

类、构造函数、析构函数

类:1、在类体中不允许对所定义的数据成员进行初始化。

2、类的成员函数描述类所表达的问题的行为。

类中所有的成员函数都必须在类体内进行说明。

但成员函数的定义既可以在类体内给出,也可以在类体外给出。

第一种方式是将成员函数直接定义在类的内部。

第二种方式是在类声明中给出对成员函数的说明,而在类外部对成员函数进行定义(但成员函数仍然在类范围内)。

这种在类外部定义的成员函数的一般格式是:<返回类型><类名>::<成员函数名>(<参数表>){<函数体>}在类体外定义成员函数时,要注意必须在成员函数名前加上类名和作用域运算符(::)。

作用域运算符用来标识某个成员属于某个类。

作用域运算符的使用格式如下:<类名>::<成员函数名>(<参数表>)或<类名>::<数据成员名>成员函数的两种定义方式之间是有差别的。

如果一个成员函数的声明和定义都在类体内,那么这个成员函数就是内联函数。

如果一个成员函数的声明在类体内,而定义在类体外,这时对该成员函数的调用是按一般函数进行的。

如果要将定义在类体外的成员函数也作为内联函数处理,就必须在成员函数的定义前加上关键字“inline”,以此显式地说明该成员函数也是一个内联函数。

成员函数除了可以定义为内联函数以外,也可以进行重载,可以对其参数设置默认值。

6.3 构造函数和析构函数1、构造函数和析构函数的定义。

构造函数的作用是在对象被创建时利用特定的值构造对象,将对象初始化为一种特定的状态,使该对象具有区别于其他对象的特征。

构造函数在对象被创建的时候由系统自动调用。

构造函数也是类的成员函数,但它是一种特殊的成员函数,它除了具有一般成员函数的特性之外,还具有一些特殊的性质:(1)构造函数的名字必须与类名相同;(2)构造函数不指定返回类型,它隐含有返回值,由系统内部使用;(3)构造函数可以有一个或多个参数,因此构造函数可以重载;(4)在创建对象时,系统会自动调用构造函数。

2、缺省构造函数和缺省析构函数缺省构造函数就是调用时不必提供参数的构造函数。

构造函数和析构函数和复制构造函数

构造函数和析构函数和复制构造函数

实验五【实验内容】构造函数和析构函数和复制构造函数构造函数1. 构造函数是类的一个特殊成员函数,它的函数名与类名相同。

2. 构造函数定义了对象数据成员的初始化方法,它只在创建对象时被系统自动调用,并且只在创建对象时调用一次,是为创建的对象分配内存空间和对数据成员进行初始化。

3. 构造函数无函数类型,没有返回值,一般都声明为公有函数。

4.C++规定,每个类必须有构造函数,没有构造函数就不能创建对象。

5.如果程序中未声明构造函数,则系统自动产生出一个默认形式的构造函数,如果提供了一个构造函数,系统就不能自动提供一个默认的构造函数。

6.构造函数可以重载,即可以定义多个参数及参数类型不同的构造函数。

复制构造函数又称拷贝构造函数,是一种特殊的构造函数,其形参为本类的对象引用。

功能是把初始值对象的每个数据成员的值都复制到新建立的对象。

如果程序员没有为类声明拷贝初始化构造函数,则编译器自己生成一个拷贝构造函数。

1. 当用类的一个对象去初始化该类的另一个对象时系统自动调用它实现拷贝赋值。

2. 若函数的形参为类对象,调用函数时,实参赋值给形参,系统自动调用拷贝构造函数。

3. 当函数的返回值是类对象时,系统自动调用拷贝构造函数。

析构函数析构函数也是特殊的类成员函数,它没有返回类型,没有参数,不能随意调用,也没有重载,只有在类的生命周期结束的时候,由系统自动调用。

析构函数和构造函数的最主要的区别:调用期不同、构造函数可以有参数可以重载。

实验1设计一个学生类stu,其中含有数据成员name、english和math,分别表示学生的姓名、英语成绩与数学成绩,使用类的成员函数output 和total输出学生的基本信息和总成绩,并完成在main函数中的相应调用。

#include <iostream>using namespace std;class stu{public:stu(char n[]="",double e=0.0,double m=0.0);~stu();void input();void output();void total();private:char name[8];double english,math;};stu::stu(char n[],double e,double m){strcpy(name,n);english=e;math=m;}stu::~stu(){}void stu::input(){cout<<"请输入学生的姓名、英语成绩与数学成绩:"<<endl;cin>>name>>english>>math;}void stu::output (){cout<<"学生的姓名、英语成绩与数学成绩:"<<name<<","<<english<<","<<math<<endl;}void stu::total (){cout<<"学生的总成绩是:"<<english+math<<endl;}void main(){stu s1("张思宁",95,80),s2;s2.input ();s1.output ();s1.total ();s2.output() ;s2.total ();}实验2练习书上112页例4-2,熟悉复制构造函数被调用的3种情况。

c语言构造函数和析构函数

c语言构造函数和析构函数

c语言构造函数和析构函数C语言构造函数和析构函数构造函数和析构函数是面向对象编程(OOP)中的重要概念。

它们用于在对象的创建和销毁过程中执行特定的操作。

然而,在C语言中并没有内置的构造函数和析构函数的概念,因为C语言不直接支持面向对象编程。

然而,我们可以通过一些技巧来模拟构造函数和析构函数的行为。

本文将逐步解释如何实现这些概念,并探讨构造函数和析构函数在C语言中的应用。

第一步:模拟构造函数构造函数在对象创建时被自动调用,用于初始化对象的成员变量。

在C语言中,我们可以通过在函数中手动分配内存并初始化对象来模拟构造函数的行为。

首先,我们需要定义一个结构体来表示我们要创建的对象。

结构体可以包含多个成员变量,每个成员变量代表对象的一个属性。

例如,我们可以创建一个学生对象,其中包含姓名和年龄两个成员变量。

ctypedef struct {char name[20];int age;} Student;接下来,我们可以编写一个创建学生对象的函数,该函数将分配内存并初始化学生对象的成员变量。

cStudent* createStudent(char* name, int age) {Student* student = (Student*)malloc(sizeof(Student));strcpy(student->name, name);student->age = age;return student;}在上述代码中,我们使用malloc函数分配了一块内存,大小足够容纳一个Student结构体。

然后,我们使用strcpy函数将传入的姓名参数复制到student对象的name成员变量中,使用赋值运算符初始化age成员变量。

最后,我们将指向新创建的学生对象的指针返回。

现在,我们可以调用createStudent函数来创建一个学生对象,并访问其成员变量。

cint main() {Student* student = createStudent("Tom", 20);printf("Name: s, Age: d\n", student->name,student->age);free(student);return 0;}在上述代码中,我们首先调用createStudent函数来创建一个学生对象,并将返回的指针赋给student指针。

C++复习5大基础函数(析构函数、构造函数、内联函数、拷贝构造函数、友元函数)详解

C++复习5大基础函数(析构函数、构造函数、内联函数、拷贝构造函数、友元函数)详解

1、析构函数2、构造函数3、内联函数4、拷贝构造函数5、友元函数1、析构函数是类的一种特殊的成员函数,它会在每次删除所创建的对象时执行。

析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号(~)作为前缀,它不会返回任何值,也不能带有任何参数。

析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。

2、构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行。

构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回void。

构造函数可用于为某些成员变量设置初始值。

3、内联函数有时称作在线函数(inline)。

函数的调用是需要付出一定的时空开销的,因为系统在调用函数时,要保留现场,然后转入被调用函数去执行,调用完,再返回主调函数,此时再恢复现场,这些操作。

所谓“内联函数”就是将很简单的函数“内嵌”到调用他的程序代码中,只样做的目的是为了节约下原本函数调用时的时空开销。

但必须注意的是:作为内联函数,函数体必须十分简单,不能含有循环、条件、选择等复杂的结构,否则就不能做为内联函数了。

事实上,即便你没有指定函数为内联函数,有的编译系统也会自动将很简单的函数作为内联函数处理;而对于复杂的函数,即便你指定他为内联函数,系统也不会理会的。

内联函数也有一定的局限性。

就是函数中的执行代码不能太多了,如果,内联函数的函数体过大,一般的编译器会放弃内联方式,而采用普通的方式调用函数。

这样,内联函数就和普通函数执行效率一样了。

4、拷贝构造函数拷贝构造函数,又称复制构造函数。

复制构造函数是一种特殊的构造函数,函数的名称必须和类名称一致,它必须的一个参数是本类型的一个引用变量。

它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象.为什么需要拷贝构造函数?把参数传递给函数有三种方法,一种是传值,一种是传地址,一种是传引用。

传值与其他两种方式不同的地方在于当使用传值方式的时候,会在函数里面生成传递参数的一个副本,这个副本的内容是按位从原始参数那里复制过来的,两者的内容是相同的。

第五章答案类、构造函数、拷贝构造函数、静态成员、友元

第五章答案类、构造函数、拷贝构造函数、静态成员、友元

5.3 练习题解答1.什么是类?为什么说类是一种抽象数据类型的实现?答:类是C++语言中的一种数据类型。

这种数据类型是一种封装体,它既包含有数据结构,又包含有对这些数据所进行的若干操作。

类的获得是通过对于所要解决的问题中的客观实体的抽象,这种抽象不仅包含了它的属性,同时还有对这些属性的操作,即方法。

对实体的这种抽象可用一个标识符来表示,并可对它引用及操作,这种标识符称为类。

可见,类是抽象数据类型的一种实现。

2.类的定义格式如何?类的说明部分和实现部分各包含些什么?答:类的定义格式包含说明部分和定义部分。

类的说明部分主要有类头和类体两部分。

类头定义格式如下所示。

class<类名>其中,class是关键字,<类名>同标识符。

类体是由一对花括号括起来的若干成员,成员中包含数据成员和成员函数,右花括号后边有一个分号。

{〈数据成员说明〉〈成员函数说明〉};成员又分为不同的访问权限,有公有(puLlic)、私有(private)和保护(protected)3种。

类的实现部分是用来定义类中说明的成员函数(没有定义)在该部分定义。

如果类中所有成员函数都已在类体内定义了,则实现部分可以省略。

3.类的成员一般分为哪两部分?这两部分有何区别?答:类的成员一般分为数据成员和成员函数两个部分。

前一部分是用来表示状态的数据,后一部分是用来改变状态的方法(即函数)。

简单地讲,前部分是变量,后部分是函数,后部分的函数是用来对前部分的变量进行操作的。

4.从访问权限角度如何区分不同种类的成员?它们各自的特点是什么?答:从访问权限角度可以将类中成员分为三种:公有的,私有的和保护的。

公有成员可以被类体内外的程序所访问,它通常作为一个类体的对外接口。

私有成员只能对类体内的程序所访问,在类体外是不可见的。

它是类中的被隐藏部分。

保护成员对一般类而言视同私有成员,对派生类同公有成员。

它可以被其派生类中的程序访问。

5.作用域运算符的功能是什么?它的使用格式如何?答:作用域运算符::是C十十语言中的一种运算符,用来指明某个标识符的作用域,主要用于标识类中成员。

C++语法详解之封装、构造函数、析构函数

C++语法详解之封装、构造函数、析构函数

C++语法详解之封装、构造函数、析构函数⼤家先了解下什么是构造函数,什么是析构函数,作⽤是什么?构造函数(⽅法)是对象创建完成后第⼀个被对象⾃动调⽤的⽅法。

它存在于每个声明的类中,是⼀个特殊的成员⽅法。

作⽤是执⾏⼀些初始化的任务。

Php中使⽤__construct()声明构造⽅法,并且只能声明⼀个。

析构函数(⽅法)作⽤和构造⽅法正好相反,是对象被销毁之前最后⼀个被对象⾃动调⽤的⽅法。

是PHP5中新添加的内容作⽤是⽤于实现在销毁⼀个对象之前执⾏⼀些特定的操作,诸如关闭⽂件和释放内存等。

下⾯在通过具体例⼦看下C++语法详解之封装、构造函数、析构函数。

成员变量私有化,提供公共的getter和setter给外界去访问成员变量class Person {int age;public:void setAge(int age){this->age = age;}int getAge(){return this->age;}};int main(){Person person;person.setAge(10);cout << person.getAge() << endl;}堆空间在程序运⾏过程,为了能够⾃由控制内存的⽣命周期、⼤⼩,会经常使⽤堆空间的内存堆空间的申请\释放malloc \ freenew \ deletenew [] \ delete []注意申请堆空间成功后,会返回那⼀段内存空间的地址申请和释放必须是1对1的关系,不然可能会存在内存泄露现在的很多⾼级编程语⾔不需要开发⼈员去管理内存(⽐如Java),屏蔽了很多内存细节,利弊同时存在利:提⾼开发效率,避免内存使⽤不当或泄露弊:不利于开发⼈员了解本质,永远停留在API调⽤和表层语法糖,对性能优化⽆从下⼿例如开盘int类型的空间,使⽤完之后销毁int *p = (int *)malloc(sizeof(int));*p = 10;free(p);int *p2 = new int;*p2 = 20;delete p2;int *p3 = new int[3];*p = 10;*(p+1) = 20;*(p+2) = 30;delete [] (p3);堆空间的初始化memsetmemset 函数是将较⼤的数据结构(⽐如对象、数组等)内存清零的⽐较快的⽅法如下所⽰Person person;person.age = 10;person.height = 199;//从person的地址开始,每个字节都赋值为0memset(&person, 0, sizeof(person));初始化int *p1 = (int *)malloc(sizeof(int)); //*p1 未初始化int *p2 = (int *)malloc(sizeof(int));memset(p2, 0, sizeof(int));//将 *p2 的每⼀个字节都初始化为0如下⼏种⽅式int *p1 = new int; //未初始化int *p2 = new int(); //被初始化为0int *p3 = new int(5); //被初始化为5int *p4 = new int[3]; //数组元素未被初始化int *p5 = new int[3](); //3个数组元素都被初始化0int *p6 = new int[3]{}; //3个数组元素都被初始化0int *p7 = new int[3]{5}; //数组⾸元素被初始化为5,其他元素被初始化为0构造函数(Constructor)构造函数(也叫构造器),在对象创建的时候⾃动调⽤,⼀般⽤于完成对象的初始化⼯作特点函数名与类同名,⽆返回值(void都不能写),可以有参数,可以重载,可以有多个构造函数⼀旦⾃定义了构造函数,必须⽤其中⼀个⾃定义的构造函数来初始化对象注意通过malloc分配的对象不会调⽤构造函数⼀个⼴为流传的、很多教程\书籍都推崇的错误结论:默认情况下,编译器会为每⼀个类⽣成空的⽆参的构造函数正确理解:在某些特定的情况下,编译器才会为类⽣成空的⽆参的构造函数⽐如我们⾃⼰写2个构造函数class Person{public:int age;Person(){cout << "Person()" << endl;}Person(int age){cout << "Person(int age))" << endl;}};在不同的空间调⽤的时候,如下区别// 全局区Person p1; //调⽤Person()Person p2(); //这是⼀个函数,函数名是p2,返回值类型是Person,⽆参Person p3(18); //调⽤ Person(int)int main(){//栈空间Person p4; //调⽤Person()Person p5(); //这是⼀个函数,函数名是p5,返回值类型是Person,⽆参Person p6(18); //调⽤ Person(int)//堆空间Person *p7 = new Person; //调⽤Person()Person *p8 = new Person(); //调⽤Person()Person *p9 = new Person(20); //调⽤ Person(int)}析构函数析构函数(也叫析构器),在对象销毁的时候⾃动调⽤,⼀般⽤于完成对象的清理⼯作特点函数名以~开头,与类同名,⽆返回值(void都不能写),⽆参,不可以重载,有且只有⼀个析构函数注意通过malloc分配的对象free的时候不会调⽤析构函数构造函数、析构函数要声明为public,才能被外界正常使⽤例如下⾯的代码class Cat{public:int age;Cat(){cout << "Cat()" << endl;}~Cat(){cout << "~Cat()" << endl;}};class Person{public:int age;Cat *cat;Person(){this->cat = new Cat();cout << "Person()" << endl;}~Person(){cout << "~Person()" << endl;}};int main(){{Person person;}return 0;}输出Cat()Person()~Person()当person销毁的时候,其持有的cat并没有销毁。

(完整版)C++试题及答案

(完整版)C++试题及答案

C++考试试卷1.已知:char *s="123456"; 则cout<<s+2; 的输出结果为()。

A) 123456 B) 3 C) 3456 D) 22.已知:char *s="abcde"; 则sizeof(s)、sizeof(*s)、strlen(s)的值依次为()。

A) 6 1 5 B) 4 1 5 C) 6 5 4 D) 4 4 53.下列语句中正确的是()。

A)char *s; *s="abcdefg";B)char *s; cin>>s;C)char *s1="abcd",*s2="efghijk";strcpy(s1,s2);D)char *s="abcdefg"; cout<<*s;4.C++中,关于构造函数和析构函数,正确的描述是()。

A)在定义类时,必须自定义构造函数和析构函数,在创建对象时自动调用构造函数,在释放对象时自动调用析构函数B)构造函数和析构函数均可以重载C)已知类Student 以及Student *p; 在使用p=new Student;时自动调用无参构造函数创建动态对象,在delelte p;时自动调用析构函数释放动态对象D)构造函数和析构函数都可以成为虚函数5.关于拷贝构造函数的描述正确的是()。

A)通常的拷贝构造函数的参数是对象的指针类型B)如果不自定义拷贝构造函数,系统提供默认的拷贝构造函数C)如果有自定义的构造函数,系统就不再提供拷贝构造函数D)如果需要用已有对象为新创建的对象初始化时,就必须自定义拷贝构造函数6.有关静态成员的描述错误的是()。

A)某个类的静态数据成员由该类的所有对象所共享B)类的公有静态数据成员既可以用类的对象访问,也可以直接用作用域运算符“::”通过类名来访问C)静态数据成员既可以是私有成员,也可以是公有成员D)类中一旦定义了静态数据成员,就必须定义静态成员函数,以便对静态数据成员进行操作7.一个类的友元函数或友元类能够通过成员访问运算符访问该类的()。

  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关键字
相关文档
最新文档