C++...
时间:2011-03-23 来源:while(2.0)
1.template类函数放cpp的链接错误
例如声明在A.h,定义在A.cpp,然后在main.cpp使用其中一个函数。编译main.cpp的时候没有问题,因为编译器看到函数的声明了,但是链接的时候有问题,因为编译A.cpp的时候编译器并不知道main里面传进来的是哪个类型,所以编A.cpp不会生成相应的二进制文件到obj里面,因此链接的时候找不到函数。办法是保证函数的实现和使用在一个obj里面,可以将实现放到.h文件中,这样由于main.cpp包含了A.h,在编译的时候就会根据使用的时候传入的模板参数生成函数二进制文件。也可以在main.cpp中include A.cpp。
2.static const和const
这里指类外面的static。static const声明的变量只能在一个obj中有效,换言之而非static的const变量可以被extern引用到另外的obj中。
3.const关键字优先修饰左边的东西,左边没有就修饰右边。
因此int *const*修饰的是前面一个*
inta = 1;
int*p = &a;
int *const* pp = &p;
pp = &p;
*pp = &a; //error
**pp = a;
4.C++的多态
多态是用虚函数表指针来实现的,每个有虚函数的类会有一个虚函数表,里面列出所有函数的入口地址,然后每个实例里面保存一个虚函数表指针,指向表头。调用函数的时候通过指针查找函数。子类继承父类的时候,如果有重载,就给子类另起一个虚函数表,把重载的函数替换成子类的。所以尽管你写的类型的基类,但是构造函数是子类的,这时虚函数表指针是子类的,调用到的就是子类的函数。构造函数不是虚函数,调用子类的构造函数完全是因为你在new后面写了,编译器有能力知道你调的是哪个构造函数。而析构函数就不同。delete的后面跟的是一个基类指针,因此只会找到基类析构函数,所以经常也需要把析构函数声明成virtual。
5.类的继承
一个类自己的private成员就是神圣不可侵犯的,无论如何也不能被别人看到。protected是保护的,可以被子类看到。三种继承方式区别只在于如果区别继承来的public和protected成员。
public继承是最宽松的了,父类的public和protected成员保持不变。
private最抠门,父类成员全部变成private。
protected把父类成员全部变成protected。
其实很好记,子类继承父类,不就惦记着父类的public和protected成员么,private的已经指望不上了。private继承就把这两样继承为private,protected就继承为protected。public呢,嘿嘿,因为父类已经声明为protected的你总不好意思再放宽成public吧,为了防止败家,父类的protected成员就还是protected吧,其他的就public了。