本文共 2701 字,大约阅读时间需要 9 分钟。
1. C++中,内存分配和对象构造紧密纠缠,就像对象析构和内存回收一样。使用new表达式的时候,先分配内存,然后再分配的内存中构造对象;使用delete表达式的时候,调用析构函数撤销对象,然后将内存返还系统。
2. 现在C++程序一般应该使用allocator类来分配内存,更加安全和灵活。allocator类是一个模板,将内存分配和对象构造分离开。比如,可以用allocator类的allocate()方法分配内存,然后用construct()方法来构造对象;用destroy()来析构对象,再用deallocate()来释放内存。
3. new表达式的过程:首先调用operator new函数来分配足够大的内存,然后运行该类型的构造函数来构造对象,最后返回指向新分配并构造的对象的指针。
4. 虽然operator new和operator delete函数的设计意图是提供给new和delete表达式使用来管理内存分配,但是也可以单独使用。
如T*newElements=alloc.allocate(newcapacity);
也可以写成T* newElements=static_cast<T*> (operator new[] (newcapacity*sizeof(T)));
operator new和delete函数与allocator类的操作的不同在于,它们是对void*指针而不是类型化指针的操作,所以需要static_cast.
5. 定位new表达式:在已分配的内存中初始化一个对象,并不经过内存分配阶段。
new (place_address) Type (initialize_list)
6. 运行时类型识别RTTI,通过两个操作符来提供RTTI:
typeid操作符,返回指针或引用所指对象的实际类型
dynamic_cast操作符,将基类类型的指针或引用安全转换为派生类型的指针或引用。
7. dynamic_cast将基类类型对象的引用或指针转换为同一继承层次中其他类型的引用或指针。如果绑定的对象不是目标类型的对象,则dynamic_cast失败。如果是转换成指针的失败,则结果是0值;如果是转换成引用的失败,则抛出bad_cast异常。
8. typeid使程序能得到一个表达式的类型,使用方法是typeid(e),e是任何类型的表达式或类型名。如果操作数不是类类型或者是没有虚函数的类,则typeid操作符指出其静态类型;如果操作数是定义了至少一个虚函数的类类型,则在运行时计算类型。
typeid最常见的用途是比较两个表达式的类型,或者将表达式与特定类型相比较。
9. 类成员指针,指向类的成员变量或者函数。成员指针包含类的类型以及成员的类型。
比如一个A类的string类型成员的指针是:string A::*pointer_name;
成员函数的指针:string(A::*pointer_name) (parameter_list);
10. 可以为成员指针定义别名,如:
typedef string (A::*Name)(parameter_list) const;
在使用的时候,可以直接定义Namea;来定义a作为一个指针。
11. 嵌套类是独立的类,基本上与外围类不相关。嵌套类的名字在其外围类的作用域中可见,但在其他类作用域或定义外围类的作用域中不可见。外围类对嵌套类的成员没有特殊访问权,嵌套类对其外围类的成员也没有特殊访问权。
在外围类的public部分定义的嵌套类,可以在任何地方使用,在protected定义的嵌套类,只能由外围类、友元、派生类访问,在private定义的嵌套类,只能被外围类和友元访问。
12. 在嵌套类外部定义的嵌套类成员,不能定义在外围类内部,而应该定义在定义外围类的作用域中。
13. 联合union是一种特殊的类,一个union对象可以有多个数据成员,但是任何时刻,只有一个成员可以有值,其他的都属于未定义。
14. 像任何类一样,union可以指定保护标记使成员成为public、private或protected。默认情况下,都是public成员。
union可以定义成员函数,包括构造函数和析构函数。但是,不能作为基类使用。union不能具有静态数据成员或引用成员,而且重要的是,不能有定义了构造函数、析构函数或赋值操作符的类类型的成员。
15. 匿名联合,不用于定义对象的未命名联合。调用匿名联合成员时,直接将其作为定义该union作用域的一部分访问。如:
class token{
union {
char c;
int I;
double d;
}
}
token k;
在访问的时候,直接用k.c来访问第一个成员。
匿名union不能有private或protected成员,也不能定义成员函数。
16. 可以在函数体内部定义类,称为局部类。
局部类只在定义它的函数作用域中可见。
局部类所有成员(包括函数)的定义必须在该类内部。
局部类没有static成员。
局部类只能访问在外围作用域中定义的类型名、static变量和枚举成员,不能使用该函数中的变量。
17. 从C语言继承来的不可移植的特征:位域和volatile限定符。
18. 位域是一种特殊的类数据成员,保存特定的位数。当程序需要将二进制数据传递给另一个程序或者硬件设备的时候,通常使用位域。
位域在内存中的布局是机器相关的。
位域必须是整形数据类型,可以使signed或者unsigned。通过在成员名后接一个冒号以指定位数。如:
class a{
unsigned int mode: 2;
}
19. 直接处理硬件的程序会有这样的数据成员,它们的值由程序本身直接控制之外的过程所控制。当可以用编译器控制或者检测之外的方式改变对象值的时候,应该将对象声明为volatile。编译器将不对这些对象进行优化。
20. 不能使用合成的复制和赋值操作符,从volatile对象进行初始化和赋值。例如,不能将volatile对象传递给普通引用或者const引用。
21. 链接指示:extern “C”。
当把include指示放在复合链接指示的花括号中时,则认为被include的头文件中的所有普通函数声明都是用链接指示的语言编写的函数。
22. 可以声明链接指示的指针,如:
extern “C” void (*pf) int;
C函数的指针与C++的指针具有不同的类型,不能互相初始化或者赋值。
23. C语言不支持函数重载。
转载地址:http://swbdi.baihongyu.com/