1.类的构造函数可以被声明为explicit,这可阻止它们被用来执行隐式类型转换(implicit type conversions),但是它们仍可被用来进行显式类型转换(explicit type conversions)
class A{ public: explicit A(); }
2.拷贝构造函数的调用:是在对象初始化的时候赋值。比如:A a1(B);或A a2 = B;
赋值操作符:是在对象初始化完成后,从另一个同类型对象中拷贝其值到自我对象。比如:A a;a=B;
3.类似C(C-like)中传值比传引用高效,面向对象C++中传引用比传值更高效。STL中传值更高效。
4.取一个const地址合法,取enum地址不合法,取#define的地址通常也不合法。如果你不希望被人霍格一个pointer或reference指向你的某个整数常量,enum可以选择。
5.对于单纯常量,最好以const对象或enum替换#define
对于形似函数的宏,最好改用inline函数 + 模板 来替换#defines宏。
6.void f1(const Widget* pw);和void f2(Widget const* pw);意义相同。
char greeting[] = "Hello"; char* p = greeting; const char* p = greeting; //p指向的值不能改变,指向的地址可变 char* const p = greeting; //p指针指向的地址不可变,指向的值可变 const char* const p = greeting; //指向的地址和值都不能变。
7.常量对象只能调用常量成员函数。
8.关键字mutable定义的变量总是能够被更改,即使在const成员函数内。比如:定义mutalbe int a;
9.将某些东西声明为const可帮助编译器侦测出错误用法。const可以被施加与任何作用域内的对象、函数参数、返回值类型、成员函数本体等等。
10.当const和non-const成员函数有着实质等价的实现时,令non-const版本调用const版本可避免重复。
比如:
const char& operator[](int p) const{...} char& operator[](int p){ return const_cast<char&>(static_cast<const TextBlock&>(*this)[p]); }
解释:cons_cast<char&> 是将返回值的const转换掉
static_cast<const TextBlock&>(*this)[p]将*this加上const,使得可以调用const版本的operator[]。
-------------------------------------------------------------------------------------------------------------------------------------
11.C++ 规定,对象的成员变量的初始化动作发生在进入构造函数本体之前。
A::A(int a, char b, C &c) { _a = a; _b = b; _c = c; }
在上面这个构造函数类,变量不是初始化,而是赋值,是基于赋值的初始化。初始化更早,发生于这些成员的default构造函数被自动调用之时,比进入构造函数体更早。
但是,对于内置类型_a、_b不一定。
A::A(int a, char b, C &c):_a(a),_b(b),_c(c){}
而这个构造函数结构砼上上面的一样,但是效率较高。对于基于赋值的初始化,它首先给变量设初值,再给予赋指定的新值。
而这个叫做成员初值列,采用copy的方式直接赋值,所以效率更高。
还有,对于内置类型(int、char等等)赋值初始化和成员初始列的效率相同。
对于有多个构造函数,且成员变量较多的情况,可以将内置类型放于构造函数体内。也可以将这些放在某个私有的函数中,可以供多个构造函数调用。
这种做法在"成员变量的值是有文件或数据库读入"的时候特别有用。
C++有着固定的成员初始化次序,基类总是在派生类之前初始化,class成员变量总是以其声明次序初始化。
-------------------------------------------------------------------------------------------------------------------------------------
12.编译单元:指产出单一目标文件的那些源码,基本上它是单一源码文件加上其所含入的头文件。
non-local static:非本地静态对象,也就是非函数体中定义的对象,包括:全局global、namespace、class中的static对象。
注:本地和非本地静态对象时相对函数而言。
问题:C++对定义于不同编译单元内的non-local static对象的初始化次序无明确定义,也就是初始化顺序不确定。
现在,至少两个源码文件,每个内至少含一个non-local static对象。现在如果某个编译单元内的某个non-local static对象的初始化使用了另一编译单元的non-local对象,而这个对象可能没有被初始化。
解决:将用到的non-local static对象般到自己的专属函数内,并在此函数内声明为static。然后返回一个指向该对象的引用。
FileSystem& getFileSystem(){ static FileSystem fs; return fs; }-------------------------------------------------------------------------------------------------------------------------------
C++保证函数体内的local static对象会在该函数被调用时,首次遇到该静态对象的定义式时初始化它。
这样替换直接访问non-local static对象,保证了能够获得一个经历初始化的对象。更好的是,如果你从未调用这个对象,就会省去构造和析构的成本。
至此,第一章我觉得需要记住的知识点就将完了。