第四五六章 数据抽象、初始化与清除
1. new与malloc的区别:(1)new是C++中的一个操作符,malloc是C的一个库函数;(2)new与delete除分配释放内存外,还调用构造与析构函数,malloc与free只分配/释放内存;(3)new检查内存泄漏时,可用的办法多些,比如重载operator new运算符;(4)new返回的是带类型的指针,malloc的返回值是void型指针;(5)new与delete在实现上可能调用了malloc与free;(6)new分配失败时,用户不需要显式处理失败情况。
2. 不要将using namespace放在头文件中,否则无法体现命名空间的作用,而且可能会引起不易发现的冲突。
3. 如果想让其它方法或类对象访问自己的私有成员,可将这些“其它方法或类”声明为友元,如:friend void g(int, X*);//在函数g内部,可访问X的私有成员。
4. private等访问控制符只在编译期起权限检查作用,编译过后的目标代码中并没有这些信息,也并没有将private及public分放在不同的特殊段中。
5. 对于实现的隐藏,C++虽然不能访问私有成员,但头文件中仍可知类的成员结构,用户可用对象首地址加偏移量方式访问对应成员。对此,一个可行的方法是,在头文件中声明一个结构体的“不完全类型说明”,如struct X;而在实现文件中实现X中变量的具体声明,这样客户可见的头文件便不可知X的具体结构了。
6. 结构体与类以C++中的区别:(1)struct中默认成员为public权限,class中默认为private;(2)从struct默认继承方式为public,而从class中继承时默认方式为private;(3)class可用在模板定义时,而struct不可以;(4)其它功能完全一样,保留struct是为了兼容等历史问题;(5)另struct在定义结构体后可以{……,……}的方式初始化成员变量,class不可以。
7. 析构函数在对象的作用域结束处调用,即使使用了goto语句也是如此,但非局部跳转(由serjmp和longjmp实现)不调析构。一般应该明确定义自己的构造函数,避免编译器生成。
8. 重载只限于参数个数,类型,顺序等。返回值类型不可重载,因为调函数时可忽略返回值。
9. 除struct和class外,umion也可以用构造函数,析构函数,成员访问控制符等,但不可以被继承。
10. C++中的const常量一般放于符号表中,不为之分配空间,默认权限只对当前文件可见。若用extern修饰了,则会为之分配空间,其它文件也可见。但是,C中默认为外部均可见。因为不分配内存,故声明一个const变量时,必须初始化。
11. const用于数组时,必须分配内存,意味着不能改变的一块内存,应尽量使用const代替宏。
12. const与Java中final的区别:(1)java中final修饰符在修饰基本类型时表示值不可改变,在修饰对象的引用时,表示引用与对象之间的对应关系不可变,但可通过对象内部的方法,改变对象本身的状态;(2)const所指的对象或基本类型一概不可改变,即使对象提供了public setX()方法也不行,而const对象也不可执行任何非const修饰的成员函数,认识它们会改变const对象的状态,不可信。
12. const int *p与int const *p效果一样,都代表指向int型const变量的指针,所以p不是const的,而所指的内容(即*p)是const的,而int * const p则表示p是const的,而*p不是。
13. extern “C”:由于C/C++处理函数名的方式不一样,因此,若想在C++中调用C中写好的方法,必须指明,如:
extern “C” void sayHello(char * str);//表示用到某个C文件中定义的sayHello函数。
14. const修饰参数时,表示参数在函数体内不会改变,修饰返回值时,表示返回值内容不可改变,也不可用modify()式的方法去改变它。
15. 如果按const引用传递参数,将意味着函数体内不可改变,与值传递性质一样,但传的时候只传地址,效率更高。
16. const修饰类的成员变量时,表示“在该类的任一对象的生命周期之内,它是不变的”,但对于这一常量而言,在不同的对象中值可不同,因为const型的成员变量在对象生成之前要初始化,所以一般采用构造函数初始化表达式的方式初始化,如:
Fred::Fred(int sz):size(sz){…}
17. const修饰方法时,表示此方法不会改变类的成员变量值,可为const对象调用。
18. mutable关键字修饰的成员变量,表示其可以在一个const对象中被改变,这种const称为逻辑const。如果想使const变量的成员能被改变,则用mutable修饰之。
19. volatile所修饰的变量,表示在编译器所知的范围内之外(多任务,多线程)此变量可能被改变,因此编译器将在读写此值时不进行优化,可并发读写之。
20. 必须用构造函数初始化列表初始化的变量有:(1)非static的const成员变量;(2)引用成员变量,引用是必须声明时初始化的,与指针不同;(3)成员变量是对象,且没有无参构造函数。因为子对象必须先初始化,且必须提供构造函数。