C++笔、面试常见题之一二

我们一定要坚信,在坚持中才能看到希望,而不是看到希望后才开始坚持

Q1:问请用简单语句告诉我C++是什么?

C++是在C语言的基础上开发的一种面向对象编程语言,应用广泛。C++融合了3种不同的编程方式:C语言代表的过程性语言、C++在C语言基础上添加的类代表的面向对象语言、C++模板支持的泛型编程。其编程领域众广,常用于系统开发、引擎开发等应用领域,是最受广大程序员受用的最强大编程语言之一,支持类及继承、封装和多态等特性

Q2:C和C++的区别?

C++在C的基础上增添类,C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现过程(事务)控制)。而对于C++,首要考虑的是如何构造一个对象模型,让这个模型能够契合与之对应的问题域,这样就可以通过获取对象的状态信息得到输出或实现过程(事务)控制。

Q3:什么是面向对象(OOP)?

面向对象是一种对现实世界理解和抽象的方法、思想,通过将需求要素等转化为对象进行问题处理的思想。面向对象编程的本质是设计并扩展自己的数据类型。
用一张图展示就是:
图片

Q3:指针和引用的区别?

序 号描述指针引用
1定义是一个变量,存储的是一个内存地址变量的别名
2初始化可以为空值不可以为空值,且必须初始化
3多级可以多级只能一级
4改变值初始化后可以改变,即指向其他的存储单元初始化后不可以再改变
5sizeof得到的是指针本身的大小所指向的变量的大小
6内存分配指针需要分配内存空间引用不需要分配
7解引用指针需要解引用引用无需解引用

注:解引用就可以理解为“解码”的意思。假设ptr里面存放的是一个内存地址,那么 * ptr就是这个内存地址里面存放的数据。前面这个“* ”的解引用操作,就可以理解为对这个ptr进行解码,解码得到的数据就是* ptr,也就是我们常说的“这个内存地址里面存放的数据”或者“这个指针指向的数据”。“指针”的理解模式太容易混淆,而“解码”的理解模式更好记一点。

Q4:const在函数中可以作用在哪些地方,意义分别是啥?

const int num(int x);代表num函数的返回值是int类型的常量
int num(int x) const;代表的num函数不能隐形的修改参数x的值
int num(const int x);代表参数x是常量,不可以修改

Q5:new/delete 和 malloc/free 的区别?

  • 相同点:都是申请内存和释放内存
  • 本质区别:malloc/free是C/C++ 语言的标准库函数,new/delete是C++的运算符。
    对于用户自定义的对象而言,用malloc/free无法满足动态管理对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数不是运算符,不在编译器的控制范围之内,不能够把执行构造函数和析构函数的任务强加给malloc/free,因此C++需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理和释放内存工作的运算符delete。
  • 联系:C++程序要经常调用C函数,而C程序只能调用malloc/free管理动态内存。因此两者要共存。

Q6:友元的作用?

友元分为友元类和友元函数。
特点:是一种定义在类外部的普通函数或者类,但他需要在类内部进行说明。为了和类的成员函数进行区分,在说明的前面加以 friend关键字。友元不是成员函数,但是他可以访问类的私有成员。友元的作用是提高程序的运行效率,但是他破坏了程序的封装性和隐藏性。使得非成员函数可以方位类的私有成员。

Q7:虚析构函数的作用?

一般情况下,类的析构函数里面都是释放内存资源,而析构函数不被调用的话,就会发生内存泄漏。当然并不是把所有的析构函数都写成虚析构函数,因为当类里面有虚函数的时候,编译器会给类添加一个虚函数表,里面用来存放虚函数的指针,从而增加的类的空间。所有只有当类为基类时,才将析构函数写成虚析构函数。

Q8:虚继承的作用?

基本原则是在内存中只有基类成员的一份拷贝。这样通过把基类继承声明为虚拟的,就只能继承基类的一份拷贝,从而消除歧义。
class A : virtual class B{
};

Q9:宏定义的特点和实现,内联函数取代他的意义

  • 宏定义在形式和使用上像一个函数,但他使用预处理器实现,没有了参数压栈、代码生成等一系列操作。因此效率很高。
  • 虽然效率高,但是是在预处理器中实现的,所以不能进行参数的有效检测,也就不能享受C++编译器严格类型检查的好处,另外返回值也不能强制转换成可转换的合适的类型。
  • C++中引入了类和类的访问控制,这样如果一个表达式涉及到类的保护成员或者私有成员,就不能用宏定义来实现。
  • 正因为如此,引入了内联函数。内联函数的代码被放入到符号表中,在使用时直接进行替换,没有了展开的开销,效率也很高。
  • 类的内联函数也是一个真正的函数,编译器在调用一个内联函数时,会首先检查他的参数类型,保证调用正确。消除了隐患和局限性。
  • 内敛函数可以作为某个类的成员函数,当然就可以在其中使用所在类的保护成员及私有成员。
  • 内敛函数一般只会用在函数内容比较简单的时候,这样,函数的代码会在任何调用他的地方展开。内联函数最重要的使用地方是:类的存取函数。

Q10:Qt的垃圾回收机制

Qt是以对象树的形式来实现对垃圾的收集。所有继承自QOBJECT类的类,在new的时候就指定了父亲,那么在父亲delete的时候,他也被清理delete。

Q11:Qt信号槽的简单实现原理?

整个原理是比较复杂的,这里只做简单介绍,有兴趣童鞋可搜索细节

  1. 在预编译时,保存信号函数和槽函数的索引为字符串,通过宏定义来实现。
  2. 建立链接,就是讲信号索引字符串和槽函数索引字符串保存在map中,建立Key-Value的关系
  3. 当信号函数触发后,先去找字符串索引,然后再去找map值,然后找到槽函数索引字符串,然后再在分支语句中找到槽函数。至此实现,哈哈,这些可以忽悠一下了,不过细节还需准备为好。

Q12:线程和进程的区别?

  1. 进程是程序的一次执行;线程是进程的执行单元。
  2. 进程间是独立的,这表现在内存空间、上下环境。线程运行在进程中。
  3. 一般来讲,进程无法突破进程边界存取其他进程内的存储空间;而同一进程所产生的线程共享内存空间。
  4. 同一进程中的两段代码不能同时进行;除非引入多线程。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值