C++语言笔试题目
- C和C++中struct有什么区别?
Protection行为 | 能否定义函数 | |
---|---|---|
C | 无 | 否,但可以有函数指针 |
C++ | 有,默认是****private | 可以 |
- C++中virtual与inline的含义分别是什么?
虚函数的特点:如果希望派生类能够重新定义基类的方法,则在基类中将该方法定义为虚方法,这样可以启用动态联编。
内联函数的特点;使用内联函数的目的是为了提高函数的运行效率。内联函数体的代码不能过长,因为内联函数省去调用函数的时间是以代码膨胀为代价的。内联函数不能包含循环语句,因为执行循环语句要比调用函数的开销大。
- 引用和指针的区别
(1)引用被创建的同时必须被初始化(指针则可以在任何时候被初始化) 。
(2)不能有 NULL 引用,引用必须与合法的存储单元关联(指针则可以是 NULL) 。
(3)一旦引用被初始化,就不能改变引用的关系(指针则可以随时改变所指的对象) 。
- 有了 malloc/free 为什么还要 new/delete ?
malloc 与 free 是 C++/C 语言的标准库函数,new/delete 是 C++的运算符。它们都可用于申请动态内存和释放内存。 对于非内部数据类型的对象而言,光用 malloc/free 无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free 是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于 malloc/free。 因此 C++语言需要一个能完成动态内存分配和初始化工作的运算符 new,以及一个能完成清理与释放内存工作的运算符 delete。注意 new/delete 不是库函数。
- C++是不是类型安全的?
不是。两个不同类型的指针之间可以强制转换(用reinterpret cast)。
-
- void * ( * (**fp1)(int))[10]:fp1是一个指针,指向一个函数,这个函数的参数为int型,函数的返回值是一个指针,这个指针指向一个数组,这个数组有10个元素,每个元素是一个void*型指针。
- float (**(* *fp2)(int,int,int))(int): fp2是一个指针,指向一个函数,这个函数的参数为3个int型,函数的返回值是一个指针,这个指针指向一个函数,这个函数的参数为int型,函数的返回值是float型。
- int (* ( * fp3)())[10] (): fp3是一个指针,指向一个函数,这个函数的参数为空,函数的返回值是一个指针,这个指针指向一个数组,这个数组有10个元素,每个元素是一个指针,指向一个函数,这个函数的参数为空,函数的返回值是int型。
- 多态类中的虚函数表是Compile-Time,还是Run-Time时建立的?
虚函数表是在编译期就建立了,各个虚拟函数这时被组织成了一个虚拟函数的入口地址的数组.而对象的隐藏成员–虚拟函数表指针是在运行期–也就是构造函数被调用时进行初始化的,这是实现多态的关键。
- In C++, what does “explicit” mean? what does “protected” mean?
explicit关键字用来修饰类的构造函数,表明该构造函数是显式的,在某些情况下,我们要求类的使用者必须显示调用类的构造函数时就需要使用explicit
protected成员只有该类的成员函数及其派生类的成员函数可以访问。
- const关键字有哪些作用
(1)阻止变量被改变可使用const。定义该const变量时,需初始化,因为以后就没有机会再去改变它了;
(2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const;
(3)在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;
(4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量;
(5)对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值”。
- 面向对象的三个基本特征,并简单叙述之?
- 封装:将客观事物抽象成类,每个类对自身的数据和方法实行protection(private,protected,public)
- 继承:广义的继承有三种实现形式:实现继承(指使用基类的属性和方法而无需额外编码的能力)、可视继承(子窗体使用父窗体的外观和实现代码)、接口继承(仅使用属性和方法,实现滞后到子类实现)。前两种(类继承)和后一种(对象组合=>接口继承以及纯虚函数)构成了功能复用的两种方式。
- 多态:允许将子类类型的指针赋值给父类类型的指针。
- 重载(overload)、重写(override,有的书也叫做“覆盖”)、重定义(redefinition)的区别?
名称 | 名字空间 | 区别 |
---|---|---|
重载 | 同一名字空间 | 是指允许存在多个同名函数,而这些函数的参数表不同。 |
重定义/隐藏 | 不同名字空间 | 用于继承,派生类与基类的函数同名,屏蔽基类的函数 |
重写/覆盖 | 不同名字空间 | 用于继承,子类重新定义父类虚函数的方法 |
- 多态的作用?
- 隐藏实现细节,使得代码能够模块化;扩展代码模块,实现代码重用;
- 接口重用:为了类在继承和派生的时候,保证使用家族中任一类的实例的某一属性时的正确调用。
- 基类的析构函数不是虚函数,会带来什么问题?
派生类的析构函数用不上,造成内存泄漏
- 全局函数的构造函数会在main函数之前执行
- new is operator.
-
不使用额外参数交换两个数的值
a = a + b;
b = a – b;
a = a – b;
- 请你谈谈你是如何使用return语句的。
(1)return 语句不可返回指向“栈内存”的“指针”或者“引用” ,因为该内存在函数体结束时被自动销毁。
(2)要搞清楚返回的究竟是“值” 、 “指针”还是“引用” 。
(3)如果函数返回值是一个对象,要考虑 return 语句的效率