C++常见面试题总结

本文主要总结了一些常见的C++面试题。链接现在不让发,所以如果需要整理好的文档的话,请关注本篇文章底部的推广订阅公众号获取:

Cpp编程小茶馆

进入正题,下面是自己整理的文档目录截图,目前只整理了41条常见面试题,也非常欢迎大家留言补充和讨论。

目录如下:

1、C和C++的区别

1)C是面向过程的语言,是一个结构化的语言,考虑如何通过一个过程对输入进行处理得到输出;C++是面向对象的语言,主要特征是“封装、继承和多态”。封装隐藏了实现细节,使得代码模块化;派生类可以继承父类的数据和方法,扩展了已经存在的模块,实现了代码重用;多态则是“一个接口,多种实现”,通过派生类重写父类的虚函数,实现了接口的重用。

2)C和C++动态管理内存的方法不一样,C是使用malloc/free,而C++除此之外还有new/delete关键字。

3)C++中有引用,C中不存在引用的概念

2、C++中指针和引用的区别

1)指针是一个新的变量,存储了另一个变量的地址,我们可以通过访问这个地址来修改另一个变量;

引用只是一个别名,还是变量本身,对引用的任何操作就是对变量本身进行操作,以达到修改变量的目的

2)引用只有一级,而指针可以有多级

3)指针传参的时候,还是值传递,指针本身的值不可以修改,需要通过解引用才能对指向的对象进行操作

引用传参的时候,传进来的就是变量本身,因此变量可以被修改

3、结构体struct和共同体union(联合)的区别

结构体:将不同类型的数据组合成一个整体,是自定义类型

共同体:不同类型的几个变量共同占用一段内存

1)结构体中的每个成员都有自己独立的地址,它们是同时存在的;

共同体中的所有成员占用同一段内存,它们不能同时存在;

2)sizeof(struct)是内存对齐后所有成员长度的总和,sizeof(union)是内存对齐后最长数据成员的长度、

结构体为什么要内存对齐呢?

1.平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据,某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常

2.硬件原因:经过内存对齐之后,CPU的内存访问速度大大提升。

4、#define和const的区别

1)#define定义的常量没有类型,所给出的是一个立即数;const定义的常量有类型名字,存放在静态区域

2)处理阶段不同,#define定义的宏变量在预处理时进行替换,可能有多个拷贝,const所定义的变量在编译时确定其值,只有一个拷贝。

3)#define定义的常量是不可以用指针去指向,const定义的常量可以用指针去指向该常量的地址

4)#define可以定义简单的函数,const不可以定义函数

5、重载overload,覆盖(重写)override,隐藏(重定义)overwrite,这三者之间的区别

1)overload,将语义相近的几个函数用同一个名字表示,但是参数列表(参数的类型,个数,顺序不同)不同,这就是函数重载,返回值类型可以不同

特征:相同范围(同一个类中)、函数名字相同、参数不同、virtual关键字可有可无

2)override,派生类覆盖基类的虚函数,实现接口的重用,返回值类型必须相同

特征:不同范围(基类和派生类)、函数名字相同、参数相同、基类中必须有virtual关键字(必须是虚函数)

3)overwrite,派生类屏蔽了其同名的基类函数,返回值类型可以不同

特征:不同范围(基类和派生类)、函数名字相同、参数不同或者参数相同且无virtual关键字

6、new、delete、malloc、free之间的关系

new/delete,malloc/free都是动态分配内存的方式

1)malloc对开辟的空间大小严格指定,而new只需要对象名

2)new为对象分配空间时,调用对象的构造函数,delete调用对象的析构函数

既然有了malloc/free,C++中为什么还需要new/delete呢?

运算符是语言自身的特性,有固定的语义,编译器知道意味着什么,由编译器解释语义,生成相应的代码。

库函数是依赖于库的,一定程度上独立于语言的。编译器不关心库函数的作用,只保证编译,调用函数参数和返回值符合语法,生成call函数的代码。

malloc/free是库函数,new/delete是C++运算符。对于非内部数据类型而言,光用malloc/free无法满足动态对象都要求。new/delete是运算符,编译器保证调用构造和析构函数对对象进行初始化/析构。但是库函数malloc/free是库函数,不会执行构造/析构。

7、delete和delete[]的区别

delete只会调用一次析构函数,而delete[]会调用每个成员的析构函数

用new分配的内存用delete释放,用new[]分配的内存用delete[]释放

一.构造函数

构造函数是和类名相同的一个函数,它的作用是实现对象的初始化。当对象被创建时,构造函数自动被调用。

特点:

  1. 没有类型
  2. 没有返回值(也不用写void)
  3. 名字与类名相同
  4. 可重载!

作用:完成类的对象的初始化

Cdate d; //定义对象d

注意:当对象d被创建时,会自动调用构造函数 d.Cdate()。

当类中未定义构造函数时,编译器会自动假设存在以下两个默认构造函数:(此构造函数什么都不做,就是个形式)。如果作者自己定义了构造函数,则默认的构造函数不会存在。

//默认构造函数一

Cdate::Cdate()

{

}

//默认构造函数二

Cdate::Cdate(const Cdate& a)

{

}

三.析构函数

我们已经知道构造函数是在创建对象时,对其进行初始化。而析构函数与其相反,是在对象被删除前象由系统自动执行它做清理工作。

作为一个类,可能有多个对象,每个对象生命结束时都要调用析构函数,且每个对象调用一次。

特点:

  1. 无类型
  2. 无返回值
  3. 名字与类名相同
  4. 不带参数,不可重载,析构函数只有一个!
  5. 析构函数前“~” (取反符,表示逆构造函数)

作用:在对象被删除前做清理工作。

注意:对象的析构函数在对象被销毁前被调用,对象何时销毁也与其作用域相关。

例如,全局对象是在程序运行结束时销毁;

自动对象是在离开其作用域时销毁;

而动态对象是在使用delete运算符时销毁。

析构函数特别适用于当一个对象被动态分配内存空间,而在对象被销毁前希望释放它所占用的内存空间的时候。我们不会忽略初始化的重要性,却常常忽略清除的重要性,然而对销毁变量的内存清理是非常重要的。

例如,我们在堆中申请了一些内存,如果没有用完就释放,会造成内存泄露,会导致应用程序运行效率降低,甚至崩溃,不可掉以轻心。

而在c++中提供有析构函数,可以保证对象清除工作自动执行。

析构与构造的调用次序相反,即最先构造的最后被析构,最后构造的最先被析构。

7.1、虚函数、纯虚函数

虚函数:虚函数是C++中用于实现多态(polymorphism)的机制。核心理念就是通过基类访问派生类定义的函数,是C++中多态性的一个重要体现。利用基类指针访问派生类中的虚函数,这种情况下采用的是动态绑定技术。

纯虚函数:纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加“=0”.纯虚函数不能实例化对象。

抽象类的介绍

抽象类是一种特殊的类,它是为了抽象和设计的目的为建立的,它处于继承层次结构的较上层。

(1)抽象类的定义: 称带有纯虚函数的类为抽象类。

(2)抽象类的作用: 抽象类的主要作用是将有关的操作作为结果接口组织在一个继承层次结构中,由它来为派生类提供一个公共的根,派生类将具体实现在其基类中作为接口的操作。所以派生类实际上刻画了一组子类的操作接口的通用语义,这些语义也传给子类,子类可以具体实现这些语义,也可以再将这些语义传给自己的子类。

(3)使用抽象类时注意:

  • 抽象类只能作为基类来使用,其纯虚函数的实现由派生类给出。如果派生类中没有重新定义纯虚函数,而只是继承基

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cpp编程小茶馆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值