1:引用和指针有什么区别?
参考答案
本质:引用是别名,指针是地址,具体的:
• 指针可以在运行时改变其所指向的值,引用一旦和某个对象绑定就不再改变
• 从内存上看,指针会分配内存区域,而引用不会,它仅仅是一个别名
• 在参数传递时,引⽤用会做类型检查,而指针不会
• 引用不能为空,指针可以为空
2:const和define有什么区别?
参考答案
本质:define只是字符串替换,const参与编译运行,具体的:
• define不会做类型检查,const拥有类型,会执行相应的类型检查
• define仅仅是宏替换,不占⽤用内存,⽽而const会占用内存
• const内存效率更高,编译器通常将const变量保存在符号表中,而不会分配存储空间,这使得它成 为一个编译期间的常量,没有存储和读取的操作
3:define和inline有什么区别?
参考答案
本质:define只是字符串替换,inline由编译器控制,具体的:
• define只是简单的宏替换,通常会产生二义性;而inline会真正地编译到代码中
• inline函数是否展开由编译器决定,有时候当函数太大时,编译器可能选择不展开相应的函数
4:malloc和new有什么区别?
参考答案
1,malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。
2,对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。
3,因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以一个能完成清理与释放内存工作的运算符delete。注意new/delete不是库函数。
4,C++程序经常要调用C函数,而C程序只能用malloc/free管理动态内存。
5、new可以认为是malloc加构造函数的执行。new出来的指针是直接带类型信息的。而malloc返回的都是void指针。
5:C++中static关键字作用有哪些
参考答案
1、隐藏:当同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。
static可以用作函数和变量的前缀,对于函数来讲,static的作用仅限于隐藏.
2、static的第二个作用是保持变量内容的持久:存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是唯一的一次初始化。
共有两种变量存储在静态存储区:全局变量和static变量,只不过和全局变量比起来,static可以控制变量的可见范围,
说到底static还是用来隐藏的。虽然这种用法不常见
3、static的第三个作用是默认初始化为0(static变量)
4、C++中的作用
1)不能将静态成员函数定义为虚函数。
2)静态数据成员是静态存储的,所以必须对它进行初始化。 (程序员手动初始化,否则编译时一般不会报错,但是在Link时会报错误)
3)静态数据成员在<定义或说明>时前面加关键字static。
补充:请说出static和const关键字尽可能多的作用
【解答】
static关键字至少有下列n个作用:
(1)函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;
(2)在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;
(3)在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;
(4)在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;
(5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。
const关键字至少有下列n个作用:
(1)欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了;
(2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const;
(3)在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;
(4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量;
(5)对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值”。例如:
const classA operator*(const classA& a1,const classA& a2);
operator*的返回结果必须是一个const对象。如果不是,这样的变态代码也不会编译出错:
classA a, b, c;
(a * b) = c; // 对a*b的结果赋值
操作(a * b) = c显然不符合编程者的初衷,也没有任何意义。
6:C++中包含哪几种强制类型转换?他们有什么区别和联系?
参考答案
• reinterpret_cast: 转换一个指针为其它类型的指针。它也允许从一个指针转换为整数类型,反之亦 然. 这个操作符能够在非相关的类型之间转换. 操作结果只是简单的从一个指针到别的指针的值的 二进制拷贝. 在类型之间指向的内容不做任何类型的检查和转换?
class A{};
class B{};
A* a = new A;
B* b = reinterpret_cast(a);
• static_cast: 允许执行任意的隐式转换和相反转换动作(即使它是不允许隐式的),例如:应用到类 的指针上, 意思是说它允许子类类型的指针转换为父类类型的指针(这是一个有效的隐式转换), 同 时, 也能够执行相反动作: 转换父类为它的子类
class Base {};
class Derive:public Base{};
Base* a = new Base;
Derive *b = static_cast(a);
• dynamic_cast: 只用于对象的指针和引用. 当用于多态类型时,它允许任意的隐式类型转换以及相 反过程. 不过,与static_cast不同,在后一种情况里(注:即隐式转换的相反过程),dynamic_cast 会检查操作是否有效. 也就是说, 它会检查转换是否会返回一个被请求的有效的完整对象。检测在 运行时进行. 如果被转换的指针不是一个被请求的有效完整的对象指针,返回值为NULL. 对于引用 类型,会抛出bad_cast异常
• const_cast: 这个转换类型操纵传递对象的const属性,或者是设置或者是移除,例如:
class C{};
const C* a = new C;
C *b = const_cast(a);
7:简述C++虚函数作用及底层实现原理
参考答案
要点是要答出虚函数表和虚函数表指针的作用。C++中虚函数使用虚函数表和 虚函数表指针实现,虚函数表是一个类的虚函数的地址表,用于索引类本身以及父类的虚函数的地 址,假如子类的虚函数重写了父类的虚函数,则对应在虚函数表中会把对应的虚函数替换为子类的 虚函数的地址;虚函数表指针存在于每个对象中(通常出于效率考虑,会放在对象的开始地址处), 它指向对象所在类的虚函数表的地址;在多继承环境下,会存在多个虚函数表指针,分别指向对应 不同基类的虚函数表。
8:构造函数中可以调用虚函数吗?
参考答案
可以,但是没有动态绑定的效果,父类构造函数中调用的仍然是父类版本的函数,子类中调用的仍然是子类版本的函数
9:简述C++中虚继承的作用及底层实现原理?
参考答案
虚继承用于解决多继承条件下的菱形继承问题,底层实现原理与编译器相关,一般通过虚基类 指针实现,即各对象中只保存一份父类的对象,多继承时通过虚基类指针引用该公共对象,从而避 免菱形继承中的二义性问题。
参考网站:
http://www.nowcoder.com/ta/nine-chapter/review?page=69