我们一定要坚信,在坚持中才能看到希望,而不是看到希望后才开始坚持
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 | 改变值 | 初始化后可以改变,即指向其他的存储单元 | 初始化后不可以再改变 |
5 | sizeof | 得到的是指针本身的大小 | 所指向的变量的大小 |
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信号槽的简单实现原理?
整个原理是比较复杂的,这里只做简单介绍,有兴趣童鞋可搜索细节
在预编译时,保存信号函数和槽函数的索引为字符串,通过宏定义来实现。 建立链接,就是讲信号索引字符串和槽函数索引字符串保存在map中,建立Key-Value的关系 当信号函数触发后,先去找字符串索引,然后再去找map值,然后找到槽函数索引字符串,然后再在分支语句中找到槽函数。至此实现,哈哈,这些可以忽悠一下了,不过细节还需准备为好。Q12:线程和进程的区别?
进程是程序的一次执行;线程是进程的执行单元。 进程间是独立的,这表现在内存空间、上下环境。线程运行在进程中。 一般来讲,进程无法突破进程边界存取其他进程内的存储空间;而同一进程所产生的线程共享内存空间。 同一进程中的两段代码不能同时进行;除非引入多线程。新闻热点
疑难解答
图片精选