标签:
1. 
4 const和#define的区别 
对比加深 
C++ 中的const 常量类似于宏定义 
const int c = 5; ≈ #define c 5 
C++ 中的const 常量与宏定义不同 
const常量是由编译器处理的,提供类型检查和作用域检查 
宏定义由预处理器处理,单纯的文本替换
2. 
C语言中的const 变量 
C语言中 const变量是只读变量,有自己的存储空间 
C++中的const 常量 
可能分配存储空间,也可能不分配存储空间 
当const 常量为全局,并且需要在其它文件中使用,会分配存储空间 
当使用& 操作符,取 const常量的地址时,会分配存储空间 
当const int &a = 10; const 修饰引用时,也会分配存储空间 
3. 
6 引用的本质 
1)引用在 C++中的内部实现是一个常指针 
Type& name ?è Type* const name 
2) C++编译器在编译过程中使用常指针作为引用的内部实现,因此引用所占用的空间大小与指针相同。 
3)从使用的角度,引用会让人误会其只是一个别名,没有自己的存储空间。这是 C++为了实用性而做出的细节隐藏 
4. 
4)     请仔细对比间接赋值成立的三个条件 
1定义两个变量(一个实参一个形参) 
2建立关联实参取地址传给形参 
3*p形参去间接的修改实参的值 
7引用结论 
1)引用在实现上,只不过是把:间接赋值成立的三个条件的后两步和二为一 
//当实参传给形参引用的时候,只不过是c++编译器帮我们程序员手工取了一个实参地址,传给了形参引用(常量指针) 
5. 
C++ 中的 const常量可以替代宏常数定义,如: 
const int A = 3; è #define A 3 
C++ 中是否有解决方案替代宏代码片段呢?(替代宏代码片段就可以避免宏的副作用!) 
C++ 中推荐使用内联函数替代宏代码片段 
C++ 中使用inline 关键字声明内联函数 
内联函数声明时 inline关键字必须和函数定义结合在一起,否则编译器会直接忽略内联请求。 
// 宏替换和函数调用区别
6. 
C++ 编译器可以将一个函数进行内联编译 
被 C++编译器内联编译的函数叫做内联函数 
内联函数在最终生成的代码中是没有定义的 
C++ 编译器直接将函数体插入在函数调用的地方 
内联函数没有普通函数调用时的额外开销 ( 压栈,跳转,返回 ) 
说明3 : C++编译器不一定准许函数的内联请求! 
说明 4 
内联函数是一种特殊的函数,具有普通函数的特征(参数检查,返回类型等) 
内联函数是对编译器的一种请求,因此编译器可能拒绝这种请求 
内联函数由 编译器处理 ,直接将编译后的函数体插入调用的地方 
宏代码片段 由预处理器处理 ,进行简单的文本替换,没有任何编译过程 
说明5 : 
现代 C++ 编译器能够进行编译优化,因此一些函数即使没有 inline 声明,也可能被编译器内联编译 
另外,一些现代 C++ 编译器提供了扩展语法,能够对函数进行强制内联 
如: g++ 中的attribute((always_inline)) 属性 
说明6 : 
C++ 中内联编译的限制: 
不能存在任何形式的循环语句 
不能存在过多的条件判断语句 
函数体不能过于庞大 
不能对函数进行取址操作 
函数内联声明必须在调用语句之前 
编译器对于内联函数的限制并不是绝对的,内联函数相对于普通函数的优势只是省去了函数调用时压栈,跳转和返回的开销。 
因此,当函数体的执行开销远大于压栈,跳转和返回所用的开销时,那么内联将无意义。 
结论:  
1) 内联函数在编译时直接将函数体插入函数调用的地方 
2 )inline 只是一种请求,编译器不一定允许这种请求 
3 )内联函数省去了普通函数调用时压栈,跳转和返回的开销
6. 
函数重载概念 
1 函数重载概念 
函数重载 (Function Overload) 
          用同一个函数名定义不同的函数 
          当函数名和不同的参数搭配时函数的含义不同
2 函数重载的判断标准 
/* 
函数重载至少满足下面的一个条件: 
          参数个数不同 
          参数类型不同 
          参数顺序不同 
*/ 
3 函数返回值不是函数重载的判断标准 
实验 1 :调用情况分析;实验 2:判断标准
/* 
函数重载的注意事项 
          重载函数在本质上是相互独立的不同函数(静态链编) 
          重载函数的函数类型是不同的 
          函数返回值不能作为函数重载的依据 
函数重载是由函数名和参数列表决定的。 
*/ 
函数重载是发生在一个类中里面 
7. 
3)struct和 class关键字区别 
在用struct 定义类时,所有成员的默认属性为 public 
在用class 定义类时,所有成员的默认属性为 private 
8. 
1构造函数和析构函数的概念 
有关构造函数 
1构造函数定义及调用 
1) C++中的类可以定义与类名相同的特殊成员函数,这种与类名相同的成员函数叫做构造函数; 
2)构造函数在定义时可以有参数; 
3)没有任何返回类型的声明。 
2构造函数的调用 
自动调用:一般情况下C++编译器会自动调用构造函数 
手动调用:在一些情况下则需要手工调用构造函数
有关析构函数 
3)析构函数定义及调用 
         1 )C++中的类可以定义一个特殊的成员函数清理对象,这个特殊的成员函数叫做析构函数 
语法:~ClassName() 
2)析构函数没有参数也没有任何返回类型的声明 
3)析构函数在对象销毁时自动被调用 
4)析构函数调用机制 
         C++ 编译器自动调用 
7. 
4默认构造函数 
二个特殊的构造函数 
1)默认无参构造函数 
当类中没有定义构造函数时,编译器默认提供一个无参构造函数,并且其函数体为空 
2)默认拷贝构造函数 
当类中没有定义拷贝构造函数时,编译器默认提供一个默认拷贝构造函数,简单的进行成员变量的值复制 
3.3构造函数调用规则研究 
1)当类中没有定义任何一个构造函数时, c++编译器会提供默认无参构造函数和默认拷贝构造函数 
2)当类中定义了拷贝构造函数时, c++编译器不会提供无参数构造函数 
3)当类中定义了任意的非拷贝构造函数(即:当类中提供了有参构造函数或无参构造函数), c++编译器不会提供默认无参构造函数 
4 )默认拷贝构造函数成员变量简单赋值 
总结:只要你写了构造函数,那么你必须用。
构造析构阶段性总结 
1)构造函数是C++中用于初始化对象状态的特殊函数 
2)构造函数在对象创建时自动被调用 
3)构造函数和普通成员函数都遵循重载规则 
4)拷贝构造函数是对象正确初始化的重要保证 
5)必要的时候,必须手工编写拷贝构造函数 
8. 
构造函数与析构函数的调用顺序 
1)当类中有成员变量是其它类的对象时,首先调用成员变量的构造函数,调用顺序与声明顺序相同;之后调用自身类的构造函数 
2)析构函数的调用顺序与对应的构造函数调用顺序相反 
9.
用new分配数组空间时不能指定初值。如果由于内存不足等原因而无法正常分配空间,则new会返回一个空指针NULL,用户可以根据该指针的值判断分配空间是否成功。 
4)     应用举例 
9. 
//1 malloc free函数                            c 关键字 
//      new delete 操作符号                c++ 的关键字
//2 new 在堆上分配内存  delete 
//分配基础类型、分配数组类型、分配对象
//3new和malloc 深入分析 
混用测试、异同比较 
结论:     malloc 不会调用类的构造函数 
                   Free 不会调用类的析构函数 
10. 
4.1静态成员变量 
1)定义静态成员变量 
?     关键字static可以用于说明一个类的成员, 
     静态成员提供了一个同类对象的共享机制 
?     把一个类的成员说明为static时,这个类无论有多少个对象被创建,这些对象共享这个static成员 
?     静态成员局部于类,它不是对象成员 
4.2静态成员函数 
1)概念 
?     静态成员函数数冠以关键字static 
?     静态成员函数提供不依赖于类数据结构的共同操作,它没有this指针 
?     在类外调用静态成员函数用 “类名 :: ”作限定词,或通过对象调用 
2)案例 
3)疑难问题:静态成员函数中,不能使用普通变量。 
     //静态成员变量属于整个类的,分不清楚,是那个具体对象的属性。 
11. 
友元类 
?     若B类是A类的友员类,则B类的所有成员函数都是A类的友员函数 
?     友员类通常设计为一种对数据操作或类之间传递消息的辅助类 
12. 
操作符重载是C++的强大特性之一 
操作符重载的本质是通过函数扩展操作符的语义 
operator关键字是操作符重载的关键 
friend关键字可以对函数或类开发访问权限 
操作符重载遵循函数重载的规则 
操作符重载可以直接使用类的成员函数实现 
=, [], ()和 ->操作符只能通过成员函数进行重载 
++操作符通过一个 int参数进行前置与后置的重载 
C++中不要重载 &&和|| 操作符 
13.
3.1.5 继承重要说明 
1、子类拥有父类的所有成员变量和成员函数 
2、子类可以拥有父类没有的方法和属性
3、子类就是一种特殊的父类 
4、子类对象可以当作父类对象使用 
3.2派生类的访问控制 
派生类继承了基类的全部成员变量和成员方法(除了构造和析构之外的成员方法),但是这些成员的访问属性,在派生过程中是可以调整的。 
14. 
问题:如何初始化父类成员?父类与子类的构造函数有什么关系 
          在子类对象构造时,需要调用父类构造函数对其继承得来的成员进行初始化 
          在子类对象析构时,需要调用父类析构函数对其继承得来的成员进行清理 
3.3.3继承中的构造析构调用原则 
1、子类对象在创建时会首先调用父类的构造函数 
2、父类构造函数执行结束后,执行子类的构造函数 
3、当父类的构造函数有参数时,需要在子类的初始化列表中显示调用 
4、析构函数调用的先后顺序与构造函数相反 
15. 
函数重写 
在子类中定义与父类中原型相同的函数 
函数重写只发生在父类与子类之间 
/* 
在同一个类里面能实现函数重载 
          继承的情况下,发生重写 
          重载不一定 ; 
重写的定义 
          静态联编重载是 
          动态联编 
*/ 
16. 
//多态成立的三个条件 
//1 要有继承 
//2 要有函数重写。。。C 虚函数 
//3 要有父类指针(父类引用)指向子类对象 
//多态是设计模式的基础,多态是框架的基础 
17. 
01静态联编和动态联编 
1、联编是指一个程序模块、代码之间互相关联的过程。 
2、静态联编(staticbinding),是程序的匹配、连接在编译阶段实现,也称为早期匹配。 
重载函数使用静态联编。 
3、动态联编是指程序联编推迟到运行时进行,所以又称为晚期联编(迟绑定)。 
18. 
面试题1:请谈谈你对多态的理解 
多态的实现效果 
多态:同样的调用语句有多种不同的表现形态; 
多态实现的三个条件 
          有继承、有 virtual 重写、有父类指针(引用)指向子类对象。 
多态的 C++ 实现 
   virtual 关键字,告诉编译器这个函数要支持多态;不是根据指针类型判断如何调用;而是要根据指针所指向的实际对象类型来判断如何调用  
 多态的理论基础 
动态联编 PK 静态联编。根据实际的对象类型来判断重写函数的调用。 
多态的重要意义 
设计模式的基础是框架的基石。 
实现多态的理论基础 
函数指针做函数参数 
C函数指针是 C++ 至高无上的荣耀。 C函数指针一般有两种用法(正、反)。 
多态原理探究 
与面试官展开讨论 
  面试题3:谈谈你对重写,重载理解 
函数重载 
必须在同一个类中进行 
子类无法重载父类的函数,父类同名函数将被名称覆盖 
重载是在编译期间根据参数类型和个数决定函数调用 
函数重写 
必须发生于父类与子类之间 
并且父类与子类中的函数必须有完全相同的原型 
使用virtual 声明之后能够产生多态 (如果不使用virtual ,那叫重定义 ) 
多态是在运行期间根据具体对象的类型决定函数调用 
面试题8:为什么要定义虚析构函数? 
在什么情况下应当声明虚函数 
?     构造函数不能是虚函数。建立一个派生类对象时,必须从类层次的根开始,沿着继承路径逐个调用基类的构造函数 
?     析构函数可以是虚的。虚析构函数用于指引 delete 运算符正确析构动态对象 
19. 
?     当类中声明虚函数时,编译器会在类中生成一个虚函数表 
?     虚函数表是一个存储类成员函数指针的数据结构 
?     虚函数表是由编译器自动生成与维护的 
?     virtual成员函数会被编译器放入虚函数表中 
?     当存在虚函数时,每个对象中都有一个指向虚函数表的指针(C++编译器给父类对象、子类对象提前布局vptr指针;当进行howToPrint(Parent *base)函数是,C++编译器不需要区分子类对象或者父类对象,只需要再base指针中,找vptr指针即可。) 
?     VPTR一般作为类对象的第一个成员 
20. 
C++中没有Java 中的接口概念,抽象类可以模拟 Java中的接口类。(接口和协议)
标签:
原文地址:http://blog.csdn.net/beliefyou8/article/details/51915572