广工大C++专业选修考试简答题复习

1. 函数调用?

除主函数外,其他任何函数都不能单独运行,函数功能的实现是通过被主函数直接或间接调用的。
函数调用发生时,首先要将实参的值按位置从左到右传递给对应的形参变量。一般情况下实参和形参的个数及排列是一一对应的,并且对应参数应该类型匹配。
数据传递方式:
一种是:将实参的值传给形参,形参是实参的一个拷贝,这种方式称为传值方式调用。
一种是:将实参的地址传给引用型形参,这时形参与实参是同一个变量,这种方式称为引用方式调用。

2. 默认形参怎么调用?(什么是默认构造函数?默认构造函数最多可以有几个?)

构造函数中参数的值既可以通过实参传递也可以指定为某些默认的值,即用户如果不指定实参值,编译系统就使形参的值为默认值。该函数不做初始化工作,只要构造函数无参或者有参且有缺省值的,都认为是缺省构造函数。一个类只能有一个缺省构造函数。
定义:
给形参一个默认值,这样形参就不必从实参取值了。
void f2(float r=2.54);
调用:f2();//f2(2.54)
如果有多个形参,可以使每个形参都有一个默认值,也可以只对一部分形参指定默认值。但所有默认参数必须放在参数表的右侧,即先定义所有的非默认参数,再定义默认参数,这是因为函数调用时,参数自左向右逐个匹配,当实参和形参个数不一致时只有这样才能避免二义性。
void f1(float a,char c,int b =0,int c =0);
调用:f1(3.5,‘x’,5);//a=3.5,c=‘x’,b=5
调用的注意:
(1)如果函数的定义在调用之前,则应在函数定义中给出默认值。如果函数的定义在函数调用之后,则在函数调用之前需要有函数声明,此时必须在函数声明中给出默认值,在函数定义时可以不给出默认值。**也就是说必须在函数调用之前将默认值的信息通知编译系统。**由于编译是从上到下进行的,如果在函数调用之前未得到默认值信息,在编译到函数调用时,就会认为实参个数与形参个数不匹配而报错。
(2)一个函数不能既作为重载函数,又作为有默认参数的函数。因为当调用函数时,如果少写一个参数,系统无法判定是利用重载函数还是利用默认参数的函数,会出现二义性,无法执行。

3. 内联函数为什么?有什么特点,与普通函数的区别?

定义:
内联函数是在编译时,在每处调用内联函数的地方将内联函数内容展开,它使用方法很简单,只需要在函数首行的左端加一个关键字inline即可。
区别:
普通函数在被调用的时候,系统首先要到函数的入口地址去执行函数体,执行完成之后再回到函数调用的地方继续执行,函数调用时系统要建立栈空间、保护现场、传递参数以及控制程序执行的转移等,这些工作要系统时间和空间的开销,但如果函数功能简单,代码很短,但使用频率高,可以使用内联函数。内联函数不需要寻址,当执行到内联函数的时候,将此函数展开。
特点
使用内置函数可以节省运行时间,但却增加了目标程序的长度,牺牲空间换时间。因此只有对于规模很小且使用频繁的函数,才可以大大提高运行速度。因为内联函数inline指示符对于编译器而言只是一个建议,所以编译器也可以选择忽略该建议。函数体包含有复杂的结构控制语句,如switch、复杂if嵌套、while等以及无法内联展开的递归函数,都不能定义为内联,即使定义,系统也将他作为一般函数处理。

4.析构函数和构造函数的作用是什么?什么时候调用呢?

构造函数
是用来处理对象的初始化的。它是一种特殊的成员函数,与其他成员函数不同,不需要用户来调用他,而是在建立对象的时候自动执行的,每建立一个对象,就调用一次构造函数。构造函数的名字必须与类名同名,而不能任意命名,它不具有任何类型,不返回任何值。
它是在对类进行声明的时候由类的设计者来定义的,程序用户只须在定义对象的同时指定数据成员的初值即可。比如含参构造函数的调用如下:Box box1(15,30,25),无参构造函数调用如下:Box box2();其中Box为类,box1和box2为对象。
析构函数
是一种特殊的成员函数,它的作用与构造函数相反,名字是类名前面加一个~符号,它没有返回值,也没有函数类型,也没有函数参数,一个类只能有一个析构函数。
它不是删除对象,而是在撤销对象占用的内存之前完成一些清理工作,使这部分内存可以被程序分配给新的对象使用。一般当对象的生命期结束时,会自动调用析构函数。
a. 函数中定义对象,函数结束时,对象释放,也会在释放前执行析构函数。
b.静态局部对象在函数调用结束时对象并不释放,只有在main函数结束时或者调用exit结束程序时才调用static局部对象的析构函数。
c.用new动态建立对象后,当用delete释放该对象时,会先调用该对象的析构函数。

5. 怎么建立复制构造函数?它用于哪里?

在建立对象时可用同一个类的对象来初始化该对象,这时所用的构造函数称为复制构造函数,这是就会出现一个数据成员相同,函数成员共用的对象出来。
形式为:类名(类名 &对象名);,如Box(Box &b);
用于三个方面:
a.程序中需要新建立一个对象,并用另一个同类的对象对它初始化。
b.当函数的参数为类的对象时,在调用函数时需要将实参对象完整地传递给形参,也就是需要建立一个实参的拷贝,这时就是按实参复制一个形参,系统通过调用复制构造函数来实现的。
c.函数的返回值为类的对象。在函数调用完毕将返回值带回函数调用处时,此时需要将函数中对象复制一个临时对象并传给函数的调用处。

6.类的静态数据成员与函数中的静态成员有何异同?

类的静态成员为其所有对象共享,不管有多少对象,静态成员只有一份存于公用内存中,为该类所有对象公有。函数中的静态成员也位于公用内存中,不随函数调用而重新分配,所以总是保留上次进入并执行该函数后留下的信息。
(类的静态成员函数没有this指针,无法调用非静态成员,只用调用静态成员)

7.什么是this指针和作用

在对象的外部访问该对象的公有成员时,需要指明是哪一个对象,但是用对象的成员函数来访问本对象的成员时,只要给出成员名就可以实现对该对象的成员进行访问。这是因为每一个对象都有一个隐藏的this指针,它始终指向该对象,并将该指针作为一个参数自动传递给该成员函数,比如一个类创建多个对象,共用同一份成员函数拷贝,函数就是通过不同的this指针来了解取的是哪一个对象的成员数据。
(静态成员函数无this指针,它不属于具体的对象,而重载运算符的成员函数要借助this指针)

8.函数的实参和形参怎么对应?实参和形参的数目必须一致吗?什么情况下可以不同?

实参与形参从左到右应该是一一按顺序对应的,并且对应参数应该类型匹配(赋值兼容),当有缺省参数时候就可以不同。

9.函数重载的作用是什么?满足什么条件的函数才可以成为重载函数?重载函数在调用时是怎样对应的?

函数重载可以定义几个功能相似,而参数类型或者个数不同,函数名相同的函数,以适应不同情况下自动选择不同函数进行操作。函数重载的好处在于可以用相同的函数名来定义一组功能相同或类似的函数,程序的可读性增强。在定义函数重载时必须保证参数类型或者个数不同,仅仅返回值不同时不行的。
当某个函数调用到重载函数时,编译器会根据实参类型去对应调用相应的函数。匹配过程如下:
(1)如果有严格匹配的函数,就调用该函数。
(2)参数内部转换后匹配的函数,就调用该函数。
(3)通过用户定义的转换寻求匹配。

10.比较函数重载和虚函数,在概念上和使用方式有什么区别?

  • .函数重载可以用于非成员函数和类的成员函数,而虚函数只能用于类的成员函数
  • .函数重载可用于构造函数,而虚函数不能用于构造函数
  • .如果对成员函数进行重载,重载的函数与被重载的函数应该是用一个类中的成员函数,不能分属于两个不同继承层次的类,函数重载处理的是横向的重载。虚函数是对同一类族中的基类和派生类的同名函数的处理,即允许在派生类中对基类的成员函数重新定义。虚函数处理的是纵向的同名函数。
  • .重载的函数必须具有相同的函数名,函数类型可以相同也可以不同,但函数的参数个数和参数类型二者中至少有一个不同,否则在编译时无法区分。而虚函数则要求同一类族中的所有虚函数的函数名,函数类型,函数的参数个数和参数类型都全部相同,否则就不是重定义了,也就不是虚函数了
  • .函数重载是在程序编译阶段确定操作的对象的,属于静态关联。虚函数是在程序运行阶段确定操作对象的,属于动态关联。

11.什么是类域,为什么说类域是抽象的?

类域是类体所包括的范围,每一个类都有一个类域,在类域中的标识符仅在该类的类域中有效。由于类只是个说明,虽然有数据,函数和类型定义,但是并非实体,不分配内存,也就不能运行,所以是抽象的。

12.引用作为函数的参数时为什么能实现两个实参之间的数据交换?为什么对应实参不能为引用?为什么返回值为引用的函数可以作为左值?

引用变量其实就是关联变量的别名,两者占据同一个存储单元。在一个以引用为参数的函数中,交换两个参数的值,实际上就是交换两个实参的值。如果函数参数是引用,调用时需要获得实参的地址,但如果实参已经是一个引用,再进行引用会发生错误,所以实参不能为引用。函数返回引用实际上是指明了返回了相应的关联变量,所以声明返回值为引用的函数实际上是将关联变量作为左值参与运算。

13.写出含有对象成员的类的构造函数的格式,并简单说明

固定格式:类名::构造函数名(参数总表):对象成员1(参数名表1),对象成员2(参数名表2),。。。对象成员n(参数名表n){。。。。。}
冒号后用逗号隔开的是要初始化的对象成员,附在后门的参数名标1等等是依次是调用相应对象成员所属构造函数的实参表,这些表的参数来自于冒号前的参数总表,但是都没有类型名。

14.面对对象的组织和面对过程有什么不同?

因为对象的操作主要用来响应外界消息并为其他对象提供服务的,所以面对对象的程序利用消息传递机制来建立各对象之间的有效联系,协调各对象的运行。
面向过程的程序是模块化的,模块的组织具有分层的结构特点,层与层之间是调用关系。

15.类的成员函数在什么情况下应该定义为私有?这样的目的是什么?

除了接口函数和创建本类对象的构造函数和撤销该对象的析构函数外,其余成员函数应该定义为私有的,这是开发类时故意隐藏起来的,而这些往往是最复杂最关键的部分,故意隐藏为以后升级扩展留下了余地,只要接口不变,内部再怎么修改,也不用修改原来的程序。

16.用delete删除p所指向的无名对象,p指针同时也被删除了,对不对?为什么?

不对,这时是释放了p指向的无名对象所占用的内存空间,也就是撤销了无名对象,称为动态内存释放,但指针p本身没有撤销,它仍然存在,该指针所占的内存空间并未释放。

17.要实现深拷贝,自定义的拷贝构造函数应该怎样设计?

如果类中有一个数据成员为指针,该类的一个对象中的这个指针p,指向了动态分配的一个堆对象。深拷贝的时候要给新建立的对象独立分配一个堆对象。这是拷贝的构造函数应该设计为:先拷贝对象主体,再为新建对象的指针分配一个堆对象,最后用原对象的堆对象拷贝新对象的堆对象。分三步完成。

18.构造函数和析构函数可以继承吗?派生类构造函数各部分的执行次序是怎么样的?

构造函数和析构函数都不可以继承,派生类构造函数各部分的执行次序是:
1.调用基类的构造函数,按他们在派生类的声明先后顺序,依次调用。
2.调用新增成员对象的构造函数,按他们在类的定义中声明的先后顺序,依次调用。
3.派生类的构造函数体的操作。

19.什么叫派生类的同名覆盖?

如果派生类声明了一个和基类成员同名的新成员,参数表和返回值都一样,派生类中新成员就屏蔽了基类的同名成员,类似函数中的局部变量屏蔽全局变量,称为同名覆盖。

20.派生类的析构函数需完成什么任务?是否要编写对基数和成员对象的析构函数调用?为什么?

析构函数是完成善后工作,析构函数无返回类型也没有参数,不用编写基类和成员对象的析构函数,只要处理好派生类的新增一般对象的析构函数即可,因为系统会自己调用成员对象和基类的析构函数的。

21.简单叙述派生类与基类的赋值兼容规则

凡是基类所能解决的问题,公有派生类都可以解决。
在任何需要基类对象的地方都可以用公有派生类的对象来代替,这条规则称为赋值兼容规则。
a.派生类的对象可以赋值给基类对象,这时是把派生类对象从对应基类继承来的成员赋值给基类对象,反过来不行,因为派生类的新成员无值可赋。
b.可以将一个派生类对象的地址赋给基类的指针变量,但只能通过这个指针访问派生类中由基类继承来的成员,不能访问派生类的新成员。
c.派生类对象可以初始化基类的引用,引用是别名,但这个别名只能包含派生类对象中的由基类继承来的成员。

22.是否使用了虚函数就能实现运行时的多态性?怎么样才能实现运行的多态性?

不是,要实现动态多态性,必须使用基类类型的指针变量或引用,使该指针该基类的不同派生类对象,并通过该指针指向虚函数,才能实现动态的多态性。

23.什么是抽象类?含有纯虚函数的类是抽象类吗?

若定义一个类,它只能用作基类来派生出新的类,而不能用来定义对象,则称为抽象类,含有纯虚函数的类是抽象类。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值