10构造函数和析构函数
结构体构造函数与析构函数

结构体构造函数与析构函数结构体是C++程序开发中常用的一种数据类型,可以将不同的数据类型封装在一个结构体中,以便于更好地组织和管理数据,提高程序的可读性和可维护性。
在结构体中,构造函数和析构函数是很重要的成员函数之一,它们分别用于完成结构体对象的初始化和销毁操作,下面我们来具体了解一下。
一、什么是结构体构造函数?结构体构造函数是一种特殊的成员函数,用于在定义结构体对象时自动执行,来完成一些对象的初始化操作。
它的特点如下:1、构造函数名称与结构体名称一致。
2、不能有返回值,包括void也不行。
3、可以有参数列表,但不能有默认参数。
4、可以有多个重载的构造函数。
5、如果没有显式定义构造函数,则编译器会自动生成默认构造函数。
例如:struct Student{int num;char name[20];float score;Student()//默认构造函数{num = 0;strcpy(name, "No name");score = 0.0;cout << "Constructor is called." << endl;}Student(int n, char na[], float s)//重载构造函数{num = n;strcpy(name, na);score = s;cout << "Another constructor is called." << endl;}};int main(){Student s1;//调用默认构造函数Student s2(1001, "Jack", 80.5);//调用有参构造函数return 0;}在上面的代码中,我们定义了一个名为Student的结构体,它有两个构造函数:默认构造函数和重载构造函数。
在main函数中,我们分别定义了两个结构体对象s1和s2,并使用不同的方式调用了它们的构造函数。
为什么要引入构造函数和析构函数汇总

1.为什么要引入构造函数和析构函数?对象的初始化是指对象数据成员的初始化,在使用对象前,一定要初始化。
由于数据成员一般为私有的(private),所以不能直接赋值。
对对象初始化有以下两种方法:类中提供一个普通成员函数来初始化,但是会造成使用上的不便(使用对象前必须显式调用该函数)和不安全(未调用初始化函数就使用对象)。
当定义对象时,编译程序自动调用构造函数。
析构函数的功能是当对象被撤消时,释放该对象占用的内存空间。
析构函数的作用与构造函数正好相反,一般情况下,析构函数执行构造函数的逆操作。
在对象消亡时,系统将自动调用析构函数,执行一些在对象撤消前必须执行的清理任务。
2. 类的公有、私有和保护成员之间的区别是什么?①私有成员private: 私有成员是在类中被隐藏的部分,它往往是用来描述该类对象属性的一些数据成员,私有成员只能由本类的成员函数或某些特殊说明的函数(如第4章讲到的友员函数)访问,而类的外部根本就无法访问,实现了访问权限的有效控制,使数据得到有效的保护,有利于数据的隐藏,使内部数据不能被任意的访问和修改,也不会对该类以外的其余部分造成影响,使模块之间的相互作用被降低到最小。
private成员若处于类声明中的第一部分,可省略关键字private。
②公有成员public:公有成员对外是完全开放的,公有成员一般是成员函数,它提供了外部程序与类的接口功能,用户通过公有成员访问该类对象中的数据。
③保护成员protected: 只能由该类的成员函数,友元,公有派生类成员函数访问的成员。
保护成员与私有成员在一般情况下含义相同,它们的区别体现在类的继承中对产生的新类的影响不同,具体内容将在第5章中介绍。
缺省访问控制(未指定private、protected、public访问权限)时,系统认为是私有private 成员。
3. 什么是拷贝构造函数,它何时被调用?拷贝构造函数的功能是用一个已有的对象来初始化一个被创建的同类对象,是一种特殊的构造函数,具有一般构造函数的所有特性,当创建一个新对象时系统自动调用它;其形参是本类对象的引用,它的特殊功能是将参数代表的对象逐域拷贝到新创建的对象中。
编写个人信息类的构造函数与析构函数

编写个人信息类的构造函数与析构函数本文将介绍构造函数和析构函数的概念及其在个人信息类中的应用。
构造函数:构造函数是一种特殊的成员函数,它在对象被创建时被自动调用,用于初始化类的数据成员。
构造函数所执行的操作包括:为类的成员变量赋初值,为对象分配必要的资源等。
构造函数的函数名必须与类名相同,无返回值。
构造函数可以定义默认参数、重载多个版本等。
对于一个个人信息类,构造函数可能如下所示:```C++class PersonalInfo {public:PersonalInfo(); //默认构造函数PersonalInfo(string name, int age, string id); //带参数的构造函数~PersonalInfo(); //析构函数private:string m_name;int m_age;string m_id;};PersonalInfo::PersonalInfo() {m_name = "";m_age = 0;m_id = "";}```这里定义了两个构造函数,一个是默认构造函数,一个是带参数的构造函数。
默认构造函数用于在对象创建时初始化对象的数据成员。
带参数的构造函数用于在对象创建时直接初始化数据成员,避免了在后续使用中再次进行一遍初始化的麻烦。
如果需要设置默认值,那么可以通过在类中声明或定义该构造函数来实现。
用于设置姓名为“张三”,年龄为18岁,身份证号为“123456”的默认构造函数可以如下所示:析构函数:析构函数是一种特殊的成员函数,它在对象被销毁时被自动调用,用于释放对象占用的资源。
如果在构造函数中为对象分配了一些资源(如用new动态分配内存),那么在析构函数中需要释放这些资源(如用delete释放内存)。
和构造函数不同,析构函数的函数名必须与类名相同,但需要在函数名前面加上一个 ~ 符号,表示析构函数。
析构函数没有形参和返回值。
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++习题

精品文档,知识共享!〔校精品〕面向对象程序设计(2007053) > 模拟试题模拟试题试题1一、 选择题(每题2分,共30分)1.C++对C 语言作了很多改进,下列描述中( )使得C 语言发生了质变,从面向过程变成了面向对象。
A 、增加了一些新的运算符;B 、允许函数重载,并允许设置缺省参数;C 、规定函数说明必须用原型;D 、引进了类和对象的概念; 2.下列描述中,( )是错误的。
A 、内联函数主要解决程序的运行效率问题;B 、内联函数的定义必须出现在内联函数第一次被调用之前;C 、内联函数中可以包括各种语句;D 、对内联函数不可以进行异常接口声明;3.在C++中,关于下列设置缺省参数值的描述中,( )是正确的。
A 、不允许设置缺省参数值;B 、在指定了缺省值的参数右边,不能出现没有指定缺省值的参数;C 、只能在函数的定义性声明中指定参数的缺省值;D 、设置缺省参数值时,必须全部都设置; 4.( )不是构造函数的特征。
A 、构造函数的函数名与类名相同; B 、构造函数可以重载;C 、构造函数可以设置缺省参数;D 、构造函数必须指定类型说明。
5.( )是析构函数的特征。
A 、析构函数可以有一个或多个参数;B 、析构函数名与类名不同;C 、析构函数的定义只能在类体内;D 、一个类中只能定义一个析构函数;6.关于成员函数特征的下列描述中,( )是错误的。
A 、成员函数一定是内联函数; B 、成员函数可以重载;C 、成员函数可以设置缺省参数值;D 、成员函数可以是静态的;精品文档,知识共享!7.下列静态数据成员的特性中,()是错误的。
A、说明静态数据成员时前边要加修饰符static;B、静态数据成员要在类体外进行初始化;C、静态数据成员不是所有对象所共用的;D、引用静态数据成员时,要在其名称前加<类名>和作用域运算符;8.友元的作用是()。
A、提高程序的运用效率;B、加强类的封装性;C、实现数据的隐藏性;D、增加成员函数的种类;9.关于new运算符的下列描述中,()是错误的。
c++试题B

一、判断题(每题1分,共10 分)()1﹒在程序中,变量定义语句可以出现在程序的任何位置。
()2﹒说明函数原型时,必须指明每个参数的类型和名字,以及返回值类型。
()3﹒说明函数原型时,形参列表中具有缺省值的形参的右边的形参数必须都具有缺省值。
()4﹒声明和定义重载函数时,如果函数的形参完全相同,而函数的类型不同,则会引起歧义性错误。
()5﹒指针变量可以在定义时初始化,但初始化的值只能是该指针类型所指对象的地址值或NULL。
()6﹒用引用传递函数参数,将在函数作用域内直接使用变量或对象。
()7﹒基类中被说明为protected的成员,不允许其他的函数访问,但其派生类的成员函数可访问。
()8﹒若类B某成员函数定义为另一个类A的友元,则A类的所有成员函数可以直接访问类B的所有成员。
()9﹒构造函数和析构函数都可以被重载,其中析构函数还可能被定义为虚函数。
()10﹒指向常对象的指针往往用作函数的参数,目的是在保护形参指针所指对象,使它在函数执行过程中不被修改。
二、填空题(每空0.5 分,共10 分)1.对象的封装可以理解为:⑴将有关的和封装在一个对象中,形成一个基本单位,对象之间相互独立,互不干扰。
⑵将对象一部分属性和功能设置为,使之受到保护,不允许其它对象访问它们。
⑶把它的一部分属性和功能设置为,作为,以便与外界联系,接收外界消息。
2.一个类有个析构函数。
析构函数不能具有和,但声明为虚函数。
3.在类定义中使用关键字static说明的数据成员被称为数据成员。
它的特征是不管该类创建了多少个对象,而该数据成员只有一个,被该类的所有对象。
4.如果需要在派生类中访问基类的私有成员可以通过以下两种方法实现:⑴在基类中增加将派生类需要访问的私有成员声明为。
⑵将需要访问基类私有成员的派生类声明为基类的。
5.重载输入运算符>>时,其运算符函数的返回值类型应当是,第一操作参数类型也应当是,而第二操作参数应是输入类型的。
C++复习题及答案

A int a[10]B int a[2,5]
C int a[]D int *a[10]
6、如果变量x,y已经正确定义,下列语句哪一项不能正确将x,y的值进行交换(D)。
Ax=x+y,y=x-y,x=x-y
Bt=x,x=y;y=t
Ct=y,y=x,x=t
24、在定义int a[5][4];之后,对a的引用正确的是(C)。
A a[2][4]B a[5][0]
C a[0][0]D a[0,0]
25、在一个类的定义中,包含对什么成员的定义(C)。
A数据B函数
C数据和函数D数据或函数
26、在计算机上可以直接运行的程序是(D)。
AC++源程序B高级语言程序
C汇编语言程序D 机器语言程序
A 大小写字母B 下划线
C 连接符D 数字字符
17、若类X是类Y的友元类,则下列哪种访问关系是正确的(B)。
A 类X的成员不能访问类Y的私有成员
B 类X的成员可以访问类Y的私有成员
C 类Y的成员可以访问类X的私有成员
D 只有类Y的公共成员才能访问类X的私有成员
18、如果编程者没有显式定义构造函数(包括复制构造函数),C++编译器就(D)。
20、请写出与数学表达式4/3πR3相对应的C++表达式4.0/3*3.14*R*R*R。
21、在C++中,函数参数的两种传递方式分别是值传递和地址传递。
22、一个类和对象的关系,正如基本数据类型与该类型的变量一样,如int x;。
23、在一个类中定义常数据成员用关键字const,定义静态数据成员用关键字static。
南开16秋学期《面向对象程序设计》在线作业

C. 有实参
D. 以上都不正确
正确答案:
5. 有如下类声明: class Sample { int x; }; 则Sample类成员x是Sample类的()。
A. 公有数据成员
B. 保护数据成员
C. 私有数据成员
D. 以上选项都不正确
正确答案: 该类的()。
A. void print(int); void print(double);
B. void fun(int); int fun(int);
C. int max(int,int); int min(int,int);
D. void mm(); int mm();
正确答案:
26. 下面叙述中错误的是()。
A. 错误
B. 正确
正确答案:
7. 抽象类不能定义对象,但可以声明抽象类的指针或引用。
A. 错误
B. 正确
正确答案:
8. 基类类型的指针可以指向其派生类对象。
A. 错误
B. 正确
正确答案:
9. 类中所提供的成员函数可以直接访问该类的私有成员。
A. 错误
B. 正确
正确答案:
D. 类B的成员即类A的成员
正确答案:
31. 下列运算符中,()在C++中不能重载。
A. ?:
B. +
C. -
D. <=
正确答案:
32. “#include <iostream>”是()预处理命令。
A. 宏定义
B. 文件包含
C. 条件编译
D. 工程配置
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
缺省的构造函数 在定义类时,若没有定义类的构造函数,则编 译器自动产生一个缺省的构造函数,其格式为: className::className() { } 缺省的构造函数并不对所产生对象的数据成员
赋初值;即新产生对象的数据成员的值是不确定
的。
class A{ float x,y; public: A(){ }//缺省的构造函数,编译器自动产生,可以不写 float Sum(void) { return x+y; } void Set(float a,float b) { x=a; y=b;} void Print(void) { cout<<"x="<<x<<'\t'<<"y="<<y<<endl; } }; void main(void) { A a1,a2;//产生对象时,自动调用缺省的构造函数,不赋值 a1.Set (2.0,4.0); cout<<"a1: "; a1.Print (); cout<<"a1.sum="<<a1.Sum ()<<endl; a2.Print();//打印随机值 }
‘ ‘ t’ ‘ ‘ ‘ ‘ ’ ‘ ‘ ‘ ‘ \ S’ u’ d’ y’ C’ +’ +’ 0’
string
‘ ‘ t’ ‘ ‘ ‘ ‘ ’ ‘ ‘ ‘ ‘ \ S’ u’ d’ y’ C’ +’ +’ 0’
new开辟的空间
Sp
Length=strlen(string); strcpy(Sp,string); Sp=new char[Length+1];
0
10
7
每一个对象必须要有相应的构造函数
若没有显式定义构造函数, 系统默认缺省的构造函数。
class A{ 对象开辟了空间,但没有初始化 float x,y; public: 隐含的缺省的构造函数 A() {} void Print(void) { cout<<x<<'\t'<<y<<endl; } 只允许这样定义对象 };
x=a; y=b; }
void Print(void){ cout<<x<<'\t'<<y<<endl; } }; void main(void) { } A a1; A a2(3.0,30.0);
error,定义时,没有构造函 数可供调用
3 、在类中,若定义了没有参数的构造函数,或 各参数均有缺省值的构造函数也称为缺省的构造
可以用new运算符为对象分配存储空间,如: A *p; p=new A; 这时必须用delete才能释放这一空间。 delete p; 用new运算符为对象分配动态存储空间时,调 用了构造函数,用delete删除这个空间时,调用了 析构函数。当使用运算符delete删除一个由new动 态产生的对象时,它首先调用该对象的析构函数,
4.构造函数可以指定参数的缺省值。
5. 若定义的类要说明该类的对象时,构造函 数必须是公有的成员函数。如果定义的类仅 用于派生其它类时,则可将构造函数定义为 保护的成员函数。
由于构造函数属于类的成员函数,它对私有 数据成员、保护的数据成员和公有的数据成 员均能进行初始化。
class A{ float x,y; 带缺省参数的构造函数 public: A(float a, float b=10) { x=a; y=b; } A() { x=0; y=0;} 不带参数的构造函数 void Print(void) { cout<<x<<'\t'<<y<<endl; } }; void main(void) 0 { A a1, a2(20.0), a3(3.0, 7.0); 20 每一个对象必 a1.Print(); 须要有相应的 3 a2.Print(); 构造函数 a3.Print();
第十章
构造函数和析构函数
构造函数和析构函数是在类体中说明的两种
特殊的成员函数。 构造函数是在创建对象时,使用给定的值来
将对象初始化。 析构函数的功能正好相反,是在系统释放对 象前,对对象做一些善后工作。
构造函数可以带参数、可以重载,同时没有
返回值。
构造函数是类的成员函数,系统约定构造函
数名必须与类名相同。构造函数提供了初始 化对象的一种简单的方法。
class A{ float x,y; public: A(float a,float b){ x=a; y=b;}//构造函数,初始化对象 float Sum(void) { return x+y; } void Set(float a,float b) { x=a; y=b;} Print(void) { cout<<"x="<<x<<'\t'<<"y="<<y<<endl;} }; void main(void) { A a1(2.0, 3.0);//定义时调用构造函数初始化 A a2(1.0,2.0); a2.Set(10.0, 20.0); //利用成员函数重新为对象赋 值 a1.Print(); a2.Print(); }
2 、析构函数是一个特殊的成员函数,函数名必须
与类名相同,并在其前面加上字符“ ~ ”,以便和
构造函数名相区别。
3 、析构函数不能带有任何参数,不能有返回值, 不指定函数类型。
4 、一个类中,只能定义一个析构函数,析构函数
不允许重载。 5、析构函数是在撤消对象时由系统自动调用的。
在程序的执行过程中,当遇到某一对象的生存期
};
A a1(3);
1 2 2 2
void f(void) { A b(2,3);}
void main(void) { A a2(4,5); f(); f(); }
class A{ float x,y; public: A(float a, float b){x=a;y=b;cout<<"初始化自动局部对象\n";} A(){ x=0; y=0; cout<<"初始化静态局部对象\n";} A(float a){ x=a; y=0; cout<<"初始化全局对象\n"; } void Print(void){ cout<<x<<'\t'<<y<<endl; } }; A a0(100.0);//定义全局对象 void f(void) { cout<<" 进入f()函数\n";A a2(1,2); 初始化全局对象 static A a3; //初始化局部静态对象 } 进入main函数 void main(void) 初始化自动局部对象 { cout<<"进入main函数\n"; 进入f()函数 A a1(3.0, 7.0);//定义局部自动对象 f(); f(); } 初始化自动局部对象 初始化局部静态变量 进入f()函数 初始化自动局部对象
关于缺省的构造函数,说明以下几点:
1 、在定义类时,只要显式定义了一个类的 构造函数,则编译器就不产生缺省的构造函 数 2、所有的对象在定义时,必须调用构造函数 不存在没有构造函数的对象!
class A{
float x,y; 显式定义了构造函数,不产生缺
public:
省的构造函数
A(float a,float b) {
对构造函数,说明以下几点: 1. 构造函数的函ห้องสมุดไป่ตู้名必须与类名相同。构造 函数的主要作用是完成初始化对象的数据成 员以及其它的初始化工作。
2. 在定义构造函数时,不能指定函数返回值 的类型,也不能指定为void类型。
3. 一个类可以定义若干个构造函数。当定义 多个构造函数时,必须满足函数重载的原则。
A a1, a2;
对局部对象,静态对象,全局对象的初始化 对于局部对象,每次定义对象时,都要调用 构造函数。
对于静态对象,是在首次定义对象时,调用 构造函数的,且由于对象一直存在,只调用 一次构造函数。
对于全局对象,是在main函数执行之前调用 构造函数的。
class A
{ int x,y; public: A(int a){ x=a; cout<<“1\n”;} A(int a, int b) { x=a,y=b;cout<<“2\n”;}
然后再释放这个对象占用的内存空间。
class A{ float x,y; public: A(float a, float b){ x=a; y=b; cout<<"调用了构造函数\n";} void Print(void){ cout<<x<<'\t'<<y<<endl; } ~A() { cout<<"调用了析构函数\n"; } }; void main(void) { cout<<"进入main()函数\n"; A *pa1; 进入main()函数 pa1=new A(3.0, 5.0);//调用构造函数 调用了构造函数 pa1->Print(); delete pa1; //调用析构函数 3 5 cout<<"退出main()函数\n"; } 调用了析构函数 退出main()函数
class A{ float x,y; public: A(float a, float b) { x=a;y=b; } A() { x=0; y=0; } void Print(void) { cout<<x<<'\t'<<y<<endl; } }; void main(void) { A *pa1,*pa2; pa1=new A(3.0, 5.0);//用new动态开辟对象空间,初始化 pa2=new A;//用new动态开辟空间,调用构造函数初始化 pa1->Print(); pa2->Print(); delete pa1; //用delete释放空间 delete pa2; //用delete释放空间 }