C++面试基础知识——C/C++篇(一)

C++成员变量初始化顺序

1、成员变量在使用初始化列表初始化时,与构造函数中初始化成员列表的顺序无关,只与定义成员变量的顺序有关。因为成员变量的初始化次序是根据变量在内存中次序有关,而内存中的排列顺序早在编译期就根据变量的定义次序决定了。
2、如果不使用初始化列表初始化,在构造函数内初始化时,此时与成员变量在构造函数中的位置有关,即按着顺序执行初始化语句。 
3、注意:类成员在定义时,是不能初始化的 
4、注意:类中const成员常量必须在构造函数初始化列表中初始化。 
5、注意:类中static成员变量,必须在类外初始化。 
6、静态变量进行初始化顺序是基类的静态变量先初始化,然后是它的派生类。直到所有的静态变量都被初始化。这里需要注意全局变量和静态变量的初始化是不分次序的。这也不难理解,其实静态变量和全局变量都被放在公共内存区。可以把静态变量理解为带有“作用域”的全局变量。在一切初始化工作结束后,main函数会被调用,如果某个类的构造函数被执行,那么首先基类的成员变量会被初始化。
一个总的初始化顺序是这样的:

1、基类的静态变量或全局变量

2、派生类的静态变量或全局变量

3、基类的成员变量

4、派生类的成员变量

C++中4个类型转换的相关的关键字

1.static_cast------相关类型之间的转换

使用场景:如在同一类层次结构中的一个指针类型到另一个指针类型,整型到枚举类型,或者浮点型到整型等。

例:  1    int m=10;

     double n=static_cast < int > m;

    2    int * q=static_cast < int* >(malloc(100));

2.reinterpret_cast------处理互不相关类型之间的转换

使用场景:如从整型到指针,一种类型的指针到另一种类型的指针等

例: int a=10;

   double* b=reinterpret_cast(a); //b的转换结果为0x0000000a

3.dynamic_cast------处理基类型到派生类型的转换(这个说法不是很准确,为了好理解先这么写)

使用场景:基类必须有虚函数,即为多态时,可以转换

它可以将基类类型的指针或引用安全地转换为派生类型的指针或引用。当具有基类的引用或指针,但需要执行不是基类组成部分的派生类操作的时候,需要动态的强制类型转换。通常,从基类指针获得派生类行为最好的方法是通过虚函数。当使用虚函数的时候,编译器自动根据对象的实际类型选择正确的函数。但是,在某些情况下,不可能使用虚函数。这时候就需要使用dynamic_cast关键字了。但是,能用虚函数还是用虚函数最好。

与其他强制类型转换不同,dynamic_cast涉及运行时类型检查。如果绑定到引用或指针的对象不是目标类型的对象,则dynamic_cast失败。

例: 

class Base
{
public:
   virtual int test(){return 0;} //基类中存在虚函数,故在派生类中存在虚函数指针指向虚函数表。
};

class Derived:public Base
{
public:
   virtual int test(){return 1;}
};

int main()
{
Base cbase;
Derived cderived;
Base *p1=new Base;
Base *p2=new Derived;
Derived* pD1=dynamic_cast(p1);//p1没有真正指向派生类,pD1置为0
Derived* pD2=dynamic_cast(p2); //正确
//Derived& pd1=dynamic_cast(*p1);//p1没有真正指向派生类,pd1抛出异常
Derived& pd2=dynamic_cast(*p2);//正确
retur 0;
}

 4.const_cast用来移除变量的const或volatile限定符。

使用const_cast会消除被转换类型的const特性,而且只有const类型的变量才能使用。那么,什么情况下需要消除一个const变量的const特性呢?比如,有时候有的函数的形参类型为非const类型,那么如果你要将一个const类型的参数传入就会报错。所以在这种情况下需要先使用const_cast转化一下。

补充:

在上面四个类型转化关键字中,除了static_cast,其他的三个都有可能涉及到指针的类型转换。从本质上来说,指针的类型不同,并没有产生很大的差异,他们都是需要足够的内存来存放一个机器地址。“指向不同类型之各指针”间的差异,既不在其指针表示法不同,也不在其内容(代表一个地址)不同,而是在其所寻址出来的object不同。也就是说,“指针类型”会教导编译器如何解释某个特定地址中的内存内容及其大小。

所以,转换(cast)其实是一种编译器指令。大部分情况下它并不改变一个指针所含的真正地址,它只影响“被指出之内存大小和其内容”的解释方式。
 

你可能感兴趣的:(面试笔记)