您的位置:首页 > 编程语言 > C语言/C++

C++中常问道一些基本概念整理

2017-04-04 19:06 375 查看
有时候明明一些知识点是我们会的并且还能熟悉使用的,可当被人问起,却答的七零八落的,东扯一下,西扯一些,没有条理。所有我决定把c++中常被问起的基础概念总结一下,希望对各位方便有用


1.C语言和C++的区别

答:(1)C源文件后缀.C,C++源文件后缀.CPP

(2)返回值 :C中如果一个函数没有指定返回值,默认返回值类型为 int,C++如果一个函数没有返回值则必须指定为void,否则不会通过编译。

(3)参数列表:C语言中如果没有参数列表时,可以默认接受任意多个参数;但在C++中,因为严格的参数检测,没有参数列表时,默认为void,不接受任何参数。

(4)缺省参数:C语言不接受参数指定默认值;C++如果给定默认参数,调用函数可以带参,也可以不带参,如果带参,则使用指定实参,否则使用默认的实参。

(5)C++支持重载。

2.什么是引用?指针和引用的区别

答:引用:给一个已存在的对象取的别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一空间;

引用和指针的底层实现方式相同。

区别:

(1)引用在定义时必须初始化,指针没有要求

(2)一旦一个引用被初始化为指向一个对象,就不能指向其他对象,而指针可以在任何时候指向一个同类型的对象。

(3)没有NULL的引用,但是有NULL的指针

(4)在sizeof的含义不同,引用的结果为引用类型的大小,但指针始终是地址空间所占空间的大小

(5)引用自加改变变量的内容,指针自加改变指针的指向

(6)有多级指针,但没有的多级引用

(7)引用比指针使用起来相对安全

3.(1)C++的三大特性是什么

封装,继承,多态

(2) 什么是封装,什么是继承,什么是多态

封装:隐藏对象的属性和实现细节,仅对外公开接口和对象进行交互,将数据和操作方法进行有机结合。

继承:是面向对象程序设计使代码复用的重要手段,允许程序员在保存原有类特性的基础上进行扩展,增加功能,这样产生的新类称为派生类

多态:字面意思:具有多种形式或形态的情形,多态性就是将接口与实现进行分离,简单说就是实现以共同的方法,但因个体差异,采用不同策略

C++的多态分为静态多态和动态多态

静态多态:在编译期间完成,编译器根据实参的类型,可推出要调用那个函数,如果有对应的函数就调用对应的函数,否则编译出错。主要有函数重载,泛型编程。

动态多态:在程序执行的期间判断引用对象的实际类型,根据实际类型调用相应方法。主要通过虚函数实现

4.浮点数的比较为什么不直接用等号

答:(1)浮点数精度不同(float,double)

(2)寄存器与内存表示浮点数的精度不同,从内存加载到寄存器精度提升,从寄存器加载到内存精度降低,发生截断可能改变

5.结构体为什么要内存对齐

答:(1)性能问题:是一种时间和空间的权衡,以空间换时间,为了访问没对齐的数据,处理器需要做两次内存访问,而对齐只需一次

(2)移植问题:不是所有内存平台都能访问任意数据的;某些平台只能在某些地址处取某些特定的数据,否则抛出异常

6.空类对象的大小是多少,为什么

答: 空类的大小是1,

深度探索C++对象模型是这样说的:那是编译器插入一个char,使得这个class的不同实体在内存中配置独一无二的地址,也就是说这个char用来标识不同对象的

7.什么是this指针

答:类中指向当前对象的指针,指向你正在编译的类将产生的对象。

this指针的类型:类类型*const

8.类默认的6个成员函数是

答: 构造函数,拷贝构造函数,析构函数,赋值运算符的重载,取地址操作符的重载,const修饰的取地址操作符的重载

9.为什么拷贝构造参数是同类型的引用

答:为防止拷贝构造函数的无限递归。

10.类中的哪些成员要放在初始化列表中初始化

(1) 引用类型的成员

(2)const数据成员

(3)类类型的成员(该类没有缺省的构造函数)

11.为什么析构函数不能被重载

因为析构函数无参无返回值,咋重载……..

12.为什么析构函数可以是虚函数

答:在实现多态时,当用基类操作派生类,在析构时防止只析构基类而不析构派生类情况发生。

13.不能被重载的操作符有哪些?

答:成员选择符,成员对象选择符,域解析符,条件操作符

14.类的静态成员函数可以调用非静态的成员函数吗?那非静态的成员函数可以调用静态的成员函数吗?

答:类的静态成员函数没有默认的this指针,因此在它里面不能使用任何非静态成员;非静态成员函数可以调用静态成员函数,因为静态成员函数所有类对象共享的。

15.const对象可以调用非const成员函数和const成员函数吗?那非const的对象呢?

答:.const对象不可以调用非const成员函数,因为const修饰则该对象不可修改,调用非const会改变该对象,所有不行,但可以调用const成员函数,因为const成员函数不会修改它。

非const的对象可以调用const成员函数也可以调用非const的成员函数,因为它没被const修饰可选择改变也可不修改。

16.const的成员函数可以调用其他const的成员函数,非const的成员函数吗?那非const的成员函数呢?

答: const的成员函数可以调用其他const的成员函数,可以调用指针成员变量的非const的成员函数。(不改变空间所存的地址,但可以改变解引用之后地址所存的内容)

const的成员函数可以调用其他const的成员函数,可以调用非const的成员函数

17.c++建议以const/枚举/内联/去代替宏,为什么?

答:宏的优点:增强代码的复用性,提高性能;

宏的缺点:(1).不方便调试(编译阶段进行了替换)增加了代码的长度,可读性差,可维护性差,而且容易误用,还容易产生副作用

(2) 没有安全检测

相比之下:(1). const和内联函数在进行时不仅 进行替换,还会进行参数类型检测,提高程序的安全性

(2).内联函数可以是普通函数,也可以是类的成员函数;函数式宏不能作为类的成员函数。

18.malloc/free和 new/delete的区别和联系?

答:(1)他们都是动态管理内存的入口

(2)malloc/free是C/C++标准库的函数,new/free是C++操作符

(3)malloc/free只是动态分配内存空间/释放空间,new/free除了分配释放空间还会调用构造和析构函数初始化与清理

(4)malloc/free需要手动计算类型大小且返回值为void*,new/free可以自己计算大小,并且返回对应类型的指针

一定要匹配使用,匹配使用,匹配使用,……..

19.什么是浅拷贝?什么是深拷贝?什么是写实拷贝?

答:浅拷贝是编译器直接将指针的值拷贝过来,结果多个对象共用一块内存,当一个对象将这个内存释放掉,另一个对象不知道这块内存已被释放掉了,以为还有效,所以对这段内存进行操作就会发生访问违规。

深拷贝是给新的对象重新开辟一块和原对象一样的空间,并把原空间的内容拷贝过来。

写实拷贝是在需要对拷贝对象操作时,才重新开辟空间。

20.虚继承

答:首先虚继承是为解决多重继承的二义性和数据冗余,在继承时用关键字virtual修饰,如图:



21.虚函数是什么?虚表是什么?

答:虚函数:在某基类中被virtual修饰的,并在一个或多个派生类中被重新定义的成员函数,为实现多态性,通过指向派生类的基类指针或引用,访问派生类中同名覆盖的成员函数。

虚表就是一张存放虚函数地址的表。

22.重载,同名隐藏,重写覆盖的比较

答: 重载:在同一作用域,函数名相同,参数不同,返回值可以不同,为处理功能类似而处理的数据类型不同的问题。

重写覆盖:分别在基类和派生类中,函数名相同,参数相同,返回值相同,基类函数是虚函数。 因为派生类继承基类的虚函数,并且自己重写了,在派生类的对象模型中,派生类的该虚函数就直接覆盖掉了虚表中基类的该函数。

同名隐藏:分别是在基类和派生类中,函数名相同。 因为继承关系中基类和派生类中有一个函数名相同的,派生类对象调用该函数,编译器会采用就近原则去在派生类找,所有就看到派生类把基类的同名函数隐藏了。

23.为什么引入纯虚函数

答: (1)为方便使用多态特性,提供接口

(2)在很多情况下,基类本身生成对象是不合理的,比如:动物作为基类派生出老虎,狮子。但动物本身构成对象是不合理的

总之:像虚函数,纯虚函数和接口等,他们出现的意义,完全就不是为实现编程功能,而是为编程的易用和扩展,方便再次开发而提出的一种标准而已。

24.模板参数和模板的模板参数

答:模板参数传参是可以是一个模板类的类型,比如: vector< int >, 它是一个具体的类

模板的模板参数传参传的是一个模板,比如:vector

25.C/C++程序编译的过程

答: 1.预处理:展开宏定义,处理条件编译指令,处理预编译指令,删除注释,添加行号和文件标识,保留所有#pragma编译器指令。linux使用-E表示预处理

2.编译:把预处理的文件进行一系列 语法分析,语义分析及源代码优化,生成相应的汇编代码,目标代码优化

3.汇编:将汇编代码变成可以机器可以执行的命令,每一条汇编语句几乎对应一条机器指令

4.链接:一大堆目标文件,以及需要的库文件,最后生成可执行文件。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息