一、C++中的对象
在C++中,对象是一种变量,每一个对象都必须有唯一的地址。
对于下面的定义:
这在C语言中是不合法的,C语言中的结构体必须至少包含一个成员;而在C++中它是合法的定义,虽然它没有成员,但是它的大小不为0,因为前面说过在C++中每个对象都有唯一的地址。在vs2008中,它的大小为1 Byte。
二、访问控制
在C++中使用访问说明符(access specifier)来控制对类的访问。
所有的访问保护是由编译器来检查的,在运行期不做检查。程序运行期间,不存在访问说明符的信息,这时对象只是一个存储区域。
C++中的访问控制只是为编程人员提供了一种约束,来帮助他们避免一些错误。如果真的想访问那些私有成员,在运行期通过指针是可以做到的。
三、带有构造函数的结构体的初始化
无论是struct还是class,如果它们带有构造函数,则它们的初始化必须通过构造函数进行。如下所示:
2 int i;
3 S(){}
4 };
5
6 int main(){
7 S s = {1}; // Error,带有构造函数,只能通过构造函数初始化。
8 S s1; //Correct
9 return 0;
10 }
四、函数重载
名字修饰(name decoration)
为了实现函数重载,编译器使用不同的参数类型来修饰不同的函数名。例如:
2 void print(float);
它们在编译器内部的名字可能会是:_print_char和_print_float。
但是,要注意的是,编译器对于名字修饰没有统一的标准,所以不同的编译器可能产生不同的内部名。因此如果在一个编译器上使用另一个编译器编译好的库(如dll),可能会出现错误。
为什么不能使用返回值进行重载
函数只能通过参数进行重载,而不能通过返回值进行重载,请看下面的情况:
2 void f();
在程序中调用:f();
这样做,编译器无法判断f()的返回值到底是int 还是 void,因此会产生歧义。
五、联合的几个要点
在C++中,联合如同结构体一样,可以具有构造函数,析构函数,成员函数还有访问控制。
它和struct的不同之处在于存储数据的方式。对于union的使用还有一个限制——不能使用union作为基类。
匿名联合(anonymous union)
如果一个联合没有类型名和标识符,那么这个联合被称为匿名联合。匿名联合在第一次出现时创建空间,示例如下:
2 union{
3 int i;
4 float f;
5 };
6
7 i = 12; // 可以直接访问成员,不需要使用点号
8 f = 1.22;
9 return 0;
10 }
六、合理的使用默认参数
默认参数同函数重载一样,为我们提供许多方便,它们都允许我们在不同的场景下使用同一个函数名。默认参数只能放在函数声明中,通常在一个头文件中。
两条原则:
1. 在设计类时,最重要的问题是类的接口,如果设计的类容易使用和重用,便是一个好的类,其次的问题才是效率问题。
2. 默认参数是为了使函数更容易使用,特别是当某个函数的许多参数都有特定值时。不能把默认参数作为一个标志决定执行函数的哪一块,这是基本原则。
以后要看的
1. 内存对齐 默认的内存对齐,程序强制的内存对齐
2. 通过指针的运算,访问类的私有成员
3. 句柄类,对类的进一步封装,隐藏私有成员,只暴露公共的接口。
4. C标准库中的setjmp和longjmp
5. 编译器的名字修饰(name decoration)