今天笔试被虐成渣了。。
1.构造函数不能是虚函数。
如果一个类没有数据成员,只有普通的函数,那么sizeof这个类按理说应该是0,但是c++里规定是1。另一种情况,如果这个类中有虚的成员函数,那么sizeof会更大,我在mac上试过,是8,也有的书说是4。会变大是因为有虚函数的类需要维护一张虚函数表vtbl,这张表中存放了类中虚函数的入口地址,也就是函数指针。这就解释了为什么sizeof这个类大小不一的原因,因为内存的地址空间位数不一样,我是这么理解的。
那么这张表是什么时候建的呢,最早也就是构造函数的时候吧。构造函数的时候,我们只分配了内存空间,还没有格式化,更不可能维护vtbl,因此构造函数设置成虚函数是通不过编译的。
2.指针用的是堆的资源。
当我们在函数体内部写了
char *c = "hello world";
实际上也是分配了堆的内存,如果回收不好,会内存泄露。c++里面字符常量是const的,*c不能再被付其他值。
3.有关指针的运算。
执行下面的代码,输出很有意思。
#include <iostream>
using namespace std;
int main()
{
int a[3];
a[0] = 1;
a[1] = 2;
a[2] = 3;
int *p = a, *q = &a[2];
cout<<p<<endl;
cout<<q<<endl;
cout<<q - p<<endl;
}
在我电脑上的输出是:
0x23fd60
0x23fd68
2
非常直观的显示出指针的-运算符是被重载过的,执行的操作实际上是两者地址的差/sizeof(指针指向的类型),两个指针之间的加运算是没有定义的,或者说被禁止的?但是指针和int之间的加减运算是被重载过得,想起vector的迭代器,强大。
4.位域
昨天看编程之美时,看到一种结构,用来解决将帅问题的。
struct{
unsigned char a:4;
unsigned char b:4;
};
之前没见过这种用法,查了一下,原来叫位域。一般用在机构体中,为了节省空间,当一个变量所占用的位数小于一个byte时,可以这样拼接起来使用。一个位域不能超过一个字节,也不能跨越两个字节,否则的话应该按照字节对齐来处理。