码迷,mamicode.com
首页 > 编程语言 > 详细

C++基础总结

时间:2016-07-15 21:29:33      阅读:243      评论:0      收藏:0      [点我收藏+]

标签:

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中的接口类。(接口和协议)

C++基础总结

标签:

原文地址:http://blog.csdn.net/beliefyou8/article/details/51915572

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!