C++基础一波流——读《C++编程思想》

来源:互联网 发布:图片透视软件 编辑:程序博客网 时间:2024/04/30 16:25

本文主要是《C++编程思想》第一卷的读书笔记,也是对C++基础知识的一个复习。不写很基础的,记录一些自己以前没有注意的知识点。

1、对象的演化

C++的面向对象特性主要体现在对象、继承和多态上。对象就是对特性和行为进行封装。(将变量和方法整合在一起)。继承是类型之间的关系。多态使用晚绑定来实现。

晚绑定的意思就是说执行期才确定所调用的函数的准确地址,是动态多态性。引发多态最关键的一点就是使用基类指针去寻找派生类的地址,去调用派生类的函数。它的特点就是以时间换空间,以效率为代价来换取代码的简洁。实现:典型的编译器对每个包含虚函数的类创建一个称为VTABLE的表。在VTABLE中,编译器放置特定类的虚函数的地址。每个带有虚函数的类,编译器秘密的放置一个指针,称为vpointer,指向这个对象的VTABLE。当通过基类指针做虚函数调用时,编译器静态的插入能取得这个VPTR并在VTABLE表中查找函数地址的代码,这样就能调用正确的函数并引起晚捆绑的发生。

2、数据抽象

声明与定义

声明向计算机介绍名字,定义为名字分配存储空间。声明变量需要使用extern关键字;函数声明的时候可以不加参数名,只给参数类型。头文件就是用来存放声明的。

3、隐藏实现

这一节主要是讲控制外部对内部成员的存取,即public、private、protected。

它们的用处在于:(1)避开用户不需要的工具(2)设计者可以改变内部实现而不会对用户产生影响。

public内外部皆可访问,private只有内部成员函数可以方位,protected除private性质之外继承结构也可以访问而private不行。

友元是显示的声明可以访问内部成员。必须在类内声明。

Class和Struct基本相同,只是Class默认成员是私有的,而Struct是公有的。

4、初始化与清除

本节主要是和构造与析构函数相关。而两者都是从安全性的角度来考虑的。

用构造函数来确保初始化,没有返回值,与返回void是不同的。用析构函数确保清除,

5、函数重载与缺省参数

需要函数重载的原因:重用接口;构造函数。

只能通过作用范围和参数(类型/顺序/个数)来重载,不能用返回值来重载。编译器在编译时会根据这些信息重新生成内部名字。

缺省参数的规则:只有参数列表的后部参数才可以缺省,就是说缺省参数后面不能有非缺省参数。

6、常量

(1)用于值替代

C中#define的升级版,不仅可以值替代,还可以保证不被修改。

const用于集合,const int i[]={1,2,3,4};float f[i[3]];//ilegall
i[3]并不是一个常量表达式,整个才叫作常量表达式。但是你不能i[3]=2这样赋值,因为这样做,你就改变了整个作为一个常量。

(2)const与指针

-->const int *x和int const *x是一样的,都代表一个指向const int的指针。

-->使指针本身变为一个const,

int d = 1; int *const x = &d;

x的指向不能改变,但是x指向的值是可以改变的。

可以把一个非const对象的地址赋给一个const指针,但是不能把一个const对象的地址赋给一个非const指针。

(3)const用在函数参数和返回值

用作参数表示变量初值不会被改变。修饰返回值就表示这个返回值不能被改变。

7、内联函数

目的是减少函数调用过程中产生的开销。

函数体如果过大就会造成冗余。

编译过程中检查类型和调用是否正确,然后直接替换。

8、命名控制

本节主要介绍命名空间以及static的使用

名字空间

namespace 把一个全局的名字空间分成多个可管理的小空间。

和class struct union enum 的区别是:

(1)namespace 只能在全局范畴定义,之间可以互相嵌套;

(2)namespace 定义结尾的大括后右边不必跟一个分号;

(3)namespace 可以在多个头文件中用一个标识符。

每个未编译单元中都可以有一个没有名字的命名空间。

静态成员

类中的static成员会有一个单独的存储空间,静态数据属于类。

(1)静态成员必须在类内声明,在类外定义。

(2)静态成员函数只能访问静态数据成员,也只能调用其他静态成员函数,因为静态成员函数没有this指针。

9、引用和拷贝构造函数

引用是支持C++运算符重载的基础,也为函数参数传入传出提供了便利。

当创建一个引用时必须初始化指向一个存在的对象,不能改变为对另外一个对象的引用。

int& b = a; b和a就都指向了同一个地址。

void f(int&) { }void g(const int&){}void main(){    int a =1;    f(a); //OK    f(1); //error!    g(a); //OK    g(1); //OK}

拷贝构造函数

X(X&)

编译器会缺省的创建拷贝构造函数,通过将拷贝构造函数声明为私有的可以避免对象的传值调用。

10、运算符重载

语法

考虑两个因素:(1)是一元的还是二元的(2)是作为全局函数还是类的成员函数

作为成员函数时,一元的函数没有参数,二元的有一个参数;全局函数则是1个,两个。

const int& operater+ (int & a){}

11、动态对象创建

C++存在三种区域:静态存储区域(在整个程序运行期间都存在),栈(从{到}存在),堆(动态分配)

针对数组的情况,foo * fp = new foo[100]; delete []fp; 这时,delete fp 只会释放第一个元素。

12、继承和组合

简单的创建一个包含已存在的类的新类称为组合。继承和组合都是为了代码重用。

public继承将保持原访问权限,否则就都是private。

构造函数和析构函数的顺序:构造在类层次的根处开始,首先调用基类的构造函数。析构函数相反。

13、多态和虚函数

多态是面向对象程序继数据抽象和继承之后的第三个基本特征。

虚函数

晚捆绑只对virtual关键字起作用

原创粉丝点击