前言:C++作为一门面向对象的编程语言,在考研复试中本问到的几率很高,尤其是考自命题的学校,本文总结了一些常见的问题,希望可以帮到小伙伴们,一起加油!上岸!上岸!上岸!

在这里插入图片描述

文章目录

1、什么是面向对象程序设计?

  • 面向对象程序设计是一种新的程序设计范型。
  • 面向对象程序的基本元素是对象 ,面向对象程序的主要结构特点是: 第一,程序一般由类的定义和类的使用两部分组成;第二,程序中的一切操作都是通过向对象发送消息来实现的,对象接收到消息后,启动有关方法完成相应的操作 。
  • 面向对象程序设计方法模拟人类习惯的解题方法,代表了计算机程序设计新颖的思维方式。

2、什么是对象?什么是类? 对象与类的关系是什么?

  • 在现实世界中,任何事物都是对象。它可以是一个有形的具体存在的事物 ,例如一张桌子。它也可以是一个无形的、抽象的事件 ,例如一次演出。在现实世界中 ,对象一般可以表示为: 属性+行为,一个对象往往是由一组属性和一组行为构成的。
  • 在面向对象程序设计中,对象是描述其属性的数据以及对这些数据施加的一组操作封装在一起构成的统一体。在C++ 中每个对象都是由数据和操作代码(通常用函数来实现)两部分组成的。
  • 在现实世界中,类是一组具有相同属性和行为的对象的抽象
  • 类和对象之间的关系是抽象和具体的关系。类是对多个对象进行综合抽象的结果,对象又是类的个体实物 ,一个对象是类的一个实例。例如学生”是一个类,它是由许多具体的学生抽象而来的一般概念。同理,桌子 ,教师.计算机等都是类。

3、什么是消息? 消息具有什么性质?

  • 在面向对象程序设计中,一个对象向另一个对象发出的请求被称为消息。
  • 对象接收到发向它的消息时,就调用有关的方法,执行相应的操作。例如,有一个教师对象张三和一个学生对象李四,对象李四可发出消息,请求对象张三演示一个实验,当对象张三接收到这个消息后,确定应完成的操作并执行之。
  • 一般情况下 ,我们称发送消息的对象为发送者或请求者,接收消息的对象为接收者或目标对象。对象中的联系只能通过消息传递来进行。接收对象只有在接收到消息时,才能被激活 ,被激活的对象会根据消息的要求完成相应的功能。
  • 消息具有以下三个性质:
    (1) 同一个对象可以接收不同形式的多个消息,作出不同的响应。
    (2) 相同形式的消息可以传递给不同的对象,所作出的响应可以是不同的。
    (3) 对消息的响应并不是必需的,对象可以响应消息,也可以不响应。

4、什么是抽象和封装? 请举例说明。

  • 抽象是将有关事物的共性归纳、集中的过程。抽象并不打算了解全部问题 ,而只强调感兴趣的信息,忽略了与主题无关的信息。例如,在设计一个成绩管理程序的过程中,只关心学生的姓名,学号 成绩等,而对他的身高,体重等信息就可以忽略。而在学生健康信息管理系统中,身高体重等信息必须抽象出来,而成绩则可以忽略。
  • 抽象是通过特定的实例(对象)抽取共同性质后形成概念的过程。面向对象程序设计中的抽象包括两个方面: 数据抽象和代码抽(或称为行为抽象) 。前者描述某类对象的属性或状态,也就是此类对象区别于彼类对象的特征物理量;后者描述了某类对象的共同行为特征或具有的共同功能。
  • 封装就是把某个事物包围起来,使外界不知道该事物的具体内容。
  • 在面向对象程序设计中,封装是指把数据和实现操作的代码集中起来放在对象内部 ,并尽可能隐蔽对象的内部细节 。
  • 以一台洗衣机为例,说明对象的封装特征。洗衣机上有一些按键,如“启动",,当人们使用洗衣机时,只要根据需要按下“启动"或暂停等按键,洗衣机就会完成相应的工作。这些按键安装在洗衣机的表面,人们通过它们与洗衣机交流,告诉洗衣机应该做什么。我们无法(当然也没必要)操作洗衣机的内部电路和机械控制部件,因为它们被装在洗衣机里面,这对于用户来说是隐蔽的,不可见的。

5、 什么是继承? 请举例说明。

继承所表达的是类之间的相关关系,这种关系使得某类对象可以继承另外一类对象的特征和能力

eg:请添加图片描述

6、什么是单继承,多继承? 请举例说明。

  • 从继承源上分,继承分为单继承和多继承。
  • 单继承是指每个派生类只直接继承了一个基类的特征

请添加图片描述

  • 多继承是指多个基类派生出一个派生类的继承关系。例如,小孩喜欢的玩具车即继承了车的一些特性 ,还继承了玩具的一些特
    征。

请添加图片描述

7、什么是多态性? 请举例说明。

  • 面向对象系统的多态性是指不同的对象收到相同的消息时执行不同的操作
  • 有一个窗口(Window)类对象,还有一个棋子(Piece)类对象, 当我们对它们发出“移动”的消息时移动?操作在 Window 类对象和 Piece 类对象上可以有不同的行为。
  • C++ 语言支持两种多态性,即编译时的多态性和运行时的多态性。编译时的多态性是通过函数重载(包括运算符重载)来实现的,运行时的多态性是通过虚函数来实现的。

8、 面向对象程序设计的主要优点是什么?

  • 可提高程序的重用性;
  • 可控制程序的复杂性;
  • 可改善程序的可维护性;
  • 能够更好地支持大型程序设计;
  • 增强了计算机处理信息的范围;
  • 能很好地适应新的硬件环境。

9、构造函数和析构函数的主要作用是什么?它们各有什么特性?

构造函数: 一种特殊的成员函数,主要用于为对象分配空间,进行初始化。

  • 构造函数的名字必须与类名相同,而不能由用户任意命名。
  • 可以有任意类型的参数,但不能具有返回值类型。
  • 不需要用户来调用,而是在建立对象时自动执行的。

析构函数: 执行与构造函数相反的操作,通常用于执行一些清理任务,如释放分配给对象的内存空间,在写C++程序函数时每次 return 0; 之后,会自动的调用析构函数释放内存空间。

  • 析构函数名与类名相同,但它前面必须加一个波浪号(~)
  • 析构函数不返回任何返回值。在定义析构函数时,是不能说明它的类型的,甚至说明void类型也不行。
  • 析构函数没有参数,所以说是不能被重载的。
  • 析构函数只有一个
  • 撤销对象时,编译系统会自动地调用析构函数

10、 什么是对象数组?

  • 对象数组是指每一数组元素都是对象的数组 ,也就是说,若一个类有若干个对象 ,我们把这一系列的对象用一个数组来存放。
  • 对象数组的元素是对象,不仅具有数据成员 ,而且还有函数成员 。

11、什么是 this 指针? 它的主要作用是什么?

  • C++ 为成员函数提供了一个名字为 this 的指针 ,这个指针称为自引用指针
  • 每当创建一个对象时,系统就把 this 指针初始化为指向该对象,即 this 指针的值是当前被调用的成员函数所在的对象的起始地址
  • 不同的对象调用同一个成员函数时,C++ 编详器将根据成员函数的 this 指针所指向的对象来确定应该引用哪一个对象的数据成员。

12、 友元函数有什么作用?

  • 友元函数不是当前类的成员函数,而是独立于当前类的外部函数
  • 可以访问该类所有的成员 ,包括私有成员、保护成员和公有成员。
  • 当一个函数需要访问多个类时 ,友元函数非常有用 ,普通的成员函数只能访问其所属的类,但是多个类的友元函数能够访问相应的所有类的数据。此外,在某些情况,例如运算符被重载时 ,需要用到友元函数。

13、有哪几种继承方式?每种方式的派生类对基类成员的继承性如何?

  • 类的继承方式有 public(公有继承) .protected(保护继承) 和 private(私有继承)三种,不同的继承方式导致不同访问属性的基类成员在派生类中的访问属性也有所不同。
  • 基类中的私有成员。无论哪种继承方式,基类中的私有成员不允许派生类继承,即在派生类中是不可直接访问的
  • 基类中的公有成员。当类的继承方式为公有继承时,基类中的所有公有成员在派生类中仍以公有成员的身份出现,在派生类内部和派生类外部都可以访问这些成员;当类的继承方式为私有继承时,基类中的所有公有成员在派生类中都以私有成员的身份出现, 在派生类内可以访问这些成员 ,但派生类外部不能访问它们;当类的继承方式为保护继承时,基类中的所有公有成员在派生类中都以保护成员的身份出现, 在派生类内可以访问这些成员,但派生类外部不能访问它们,而在下一层派生类内可以访问它们。
  • 基类中的保护成员。当类的继承方式为公有继承时,基类中的所有保护成员在派生类中仍以保护成员的身份出现,在派生类内可以访问这些成员 ,但派生类外部不能访问它们,而在下一层派生类内可以访问它们; 当类的继承方式为秘有继承时,基类中的所有保护成员在派生类中都以秘有成员的身份出现, 在派生类内可以访问这些成员,但派生类外部不能访问它们;当类的继承方式为保护继承时,基类中的所有保护成员在派生类中仍以保护成员的身份出现,在派生类内可以访问这些成员,但派生类外部不能访问它们,而在下一层派生类内可以访问它们 。

14、 派生类能和否直接访问基类的私有成员? 若否 ,应如何实现?

  • 派生类不能直接访问基类的私有成员。
  • 可以通过基类提供的公有成员函数间接地访问基类的私有成员。

15、保护成员有哪些特性? 保护成员以公有方式或私有方式被继承后的访问特性如何?

  • 类的继承方式为公有继承时,基类中的所有保护成员在派生类中仍以保护成员的身份出现,在派生类内可以访问这些成员,但派生类外部不能访问它们,而在下一层派生类内可以访问它们。
  • 当类的继承方式为私有继承时 ,基类中的所有保护成员在派生类中都以私有成员的身份出现, 在派生类内可以访问这些成员 ,但派生类外部不能访问它们 。

16、派生类构造函数和析构函数的执行顺序是怎样的?

  • 当创建派生类对象时,首先执行基类的构造函数,随后再执行派生类的构造函数;
  • 当撤销派生类对象时,则先执行派生类的析构函数,随后再执行基类的析构函数。

17、 派生类构造函数和析构函数的构造规则是怎样的?

  • 基类的构造函数没有参数 ,或没有显式定义构造函数时 ,派生类可以不向基类传递参数,甚至可以不定义构造函数。
  • 基类含有带参数的构造函数时 ,派生类必须定义构造函数 ,以提供把参数传递给基类构造函数的途径。
  • 在派生类中可以根据需要定义自己的析构函数,用来对派生类中增加的成员进行清理工作。基类的清理工作仍然由基类的析构函数负责。
  • 由于析构函数是不带参数的,在派生类中是否要自定义析构因数与它所属基类的析构函数无关。
  • 在执行派生类的析构函数时,系统会自动调用基类的析构师数,对基类的对象进行清理。

18、什么是多继承? 多继承时,构造函数和本构函数执行顺序是怎样的?

  • 一个派生类具有多个基类时,这种派生方法称为多继承。
  • 多重继承的构造函数的执行顺序与单继承构造函数的执行顺序相同,也是遵循先执行基类的构造顺数,再执行对象成员的构造旺数,最后执行派生类构造郴数体的原则。
  • 处于同一层次的各个基类构造毅数的执行顺序 ,取决于声明派生类时所指定的各个基类的顺序 ,与
    派生类构造函数中所定义的成员初始化列表的各项顺序没有关系。
  • 析构函数的执行顺序则刚好与构造函数的执行顺序相反。

19、在类的派生中为何要引入虚基类? 虚基类构造函数的调用顺序是如何规定的?

  • 当引用派生类的成员时,首先在派生类自身的作用域中寻找这个成员,如果没有找到,则到它的基类中寻找。
  • 如果一个派生类是从多个基类派生出来的,而这些基类义有一个共同的基类,则在这个派生类中访问这个共同的基类中的成员时,可能会产生二义性为了解决这种二义性,C++ 引入了虚基类的概念
  • 虚基类的初始化与一般的多继承的初始化在语法上是一样的,但构造函数的调用顺序不同。
    (1) 如果在虚基类中定义有带形参的构造函数,并且没有定义默认形式的构造函数,则整个继承结构中,所有直接或间接的派生类都 必须在构造函数的成员初始化表中列出对虚基类构造函数的调用,以初始化在虑基类中定义的数据成员。
    (2) 建立一个对象时,如果这个对象中含有从虚基类继承来的成员,则虚基类的成员是由最远派生类的构造函数通过调用虚基类的构造函数进行初始化的。该派生类的其他基类对虚基类构造函数的调用都自动被忽略 。
    (3) 若同一层次中同时包含虚基类和非虚基类 ,应先调用虚基类的构造函数,再调用非虚基类的构造函数,最后调用派生类构造机数。
    (4) 对于多个虚基类,构造函数的执行顺序仍然是先左后右,自上而下 。
    (5) 对于非虚基类 ,构造函数的执行顺序仍是先左后右,自上而下 。
    (6) 若虚基类由非虚基类派生而来,则仍然先调用基类构造函数,再调用派生类的构造函数。

20、什么是静态联编? 什么是动态联编?

在C++ 中,多态性的实现和联编(也叫绑定)这一概念有关。

  • 一个源程序经过编译,连接,成为可执行文件的过程是把可执行代码联编(或称装配)在一起的过程。
  • 运行之前就完成的联编称为静态联编,又叫前期联编;而在程序运行时才完成的联编叫动态联编,也称后期联编。
  • 静态联编是指系统在编译时就决定如何实现某一动作。静态联编要求在程序编译时就知道调用函数的全部信息,因此,这种联编类型的函数调用速度很快,效率高。
  • 动态联编是指系统在运行时动态实现某一动作。采用这种联编方式,一直要到程序运行时才能确定调用哪个函数。动态联编的主要优点是: 提供了更好的灵活性`问题抽象性和程序易维护性。

21、编译时的多态性与运行时的多态性有什么区别? 它们的实现方法有什么不同?

静态联编支持的多态性称为编译时多态性,也称静态多态性。

  • 在C++ 中,编译时多态性是通过函数重载(包括运算符重载)和模板实现的。利用函数重载机制,在调用同
    名的函数时,编译系统可根据实参的具体情况确立所要调用的是哪个函数。

动态联编所支持的多态性称为运行时多态性,也称动态多态性。

  • 在C++ 中,运行时多态性是通过虚函数来实现的。

22、友元运算符重载函数和成员运算符重载函数有什么不同?

  • 对双目运算符而言 ,成员运算符重载函数参数表中含有一个参数,而友元运算符重载函数参数表中含有两个参数;对单目运算符而言,成员运算符重载函数参数表中没有参数,而友元运算符重载函数参数表中含有一个参数。
  • 双目运算符一般可以被重载为友元运算符重载函数或成员运算符重载函数,但有一些情况 ,必须使用友元运算符重载函数,例如一个常数与一个对象相加。有的运算符(如“=”等)只能使用成员运算符重载函数。
  • C++ 的大部分运算符既可说明为成员运算符函数,又可说明为友元运算符函数。究竟选择哪一种运算符函数好一些,没有定论,这主要取决于实际情况和程序员的习惯。

23、什么是虚函数? 虚函数与函数重载有哪些相同点与不同点?(重点)

虚函数就是在基类中被关键字 virtual 说明 ,并在派生类中重新定义的函数。虚函数的作用是允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。

  • 在一个派生类中重新定义基类的虚函数是函数重载的另一种形式,但它不同于一般的函数重载。
  • 当普通的函数重载时,其函数的参数或参数类型必须有所不同, 函数的返回类型也可以不同。但是,当重载一个虚函数时,也就是说在派生类中重新定义虚函数时,要求函数名.返回类型.参数个数 .参数的类型和顺序与基类中的虚函数原型完全相同。
  • 如果仅仅返回类型不同 ,其余均相同,系统会给出错误信息;若仅仅函数名相同 ,而参数的个数 .类型
    或顺序不同 ,系统将它作为普通的函数重载,这时虚函数的特性将丢失。

24、 什么是纯虚函数?什么是抽象类?

纯虚函数是一个在基类中说明的虚函数,它在该基类中没有定义,但要求在它的派生类中定义自己的版本 ,或重新说明为纯虚函数。

  • 声明纯虚函数的一般形式如下:virtual 函数类型 丽数名 (参数表) = 0;
  • 纯虚函数的作用是在基类中为其派生类保留一个函数的名字,以便派生类根据需要对它进行重新定义。纯虚函数没有函数体,它最后面的“=0?并不表示函数的返回值为 0,而只起形式上的作用,告诉编译系统"这是纯虚函数”。纯虚函数不具备函数的功能,不能被
    调用。
  • 如果一个类至少有一个纯虚函数 ,那么就称该类为抽象类。
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐