1. 当改变指针指向时要注意delete。
如果当前是指向自由存储器,则必须在给指针赋予新的地址前释放内存,否则以后将无法释放该地址。
int* p = new int(10);
int a = 12;
//delete p;
p = &a;
如果不先delete p,开始分配给p的内存就会一直被占用并且无法释放了。
2. 一定要给包含指针数据的类提供复制构造函数。
比如一个简单的消息类:Massage,其中只包含一个char* msg的数据成员。
Massage msg1 ("This is a msg");
Massage msg2(msg1);
如上语句将使得msg2中的char*指向msg1的char*地址,任何对msg1的修改将影响到msg2,反之亦然。我们此时希望的是都得msg1的一个副本,而不是它的地址。因此我们需要给Massage类提供一个复制构造函数,大概可以像这个样子:
Massage(const Massage& aMsg)
{
msg = new char[strlen(aMsg) + 1];
strcpy(msg, aMsg.msg);
}
另一种比较隐蔽的情况是,当你把msg1当成某函数的参数时,系统需要调用复制构造函数。假如有如下函数:void showMasage(Massage aMsg):
我们如果使用showMassge(msg1),该函数会正常工作,但是,在该函数返回之后,msg1将无法再使用。因为当msg1作为实参传递给showMassge之后,系统将自动生成一个它的副本:aMsg。不过假如我们没有提供复制构造函数,aMsg和msg1的char*将指向同一个地址,而aMsg将在showMassage返回时被销毁,它指向的那块内存也会同时被释放,不幸的是,msg1也"碰巧"指向了这个被释放的地址,以后想使用msg1将会导致不可预测的结果。
因此,只要类的数据成员中包含指针,我们就应该为其提供复制构造函数。
3. const char * p, char * const p, char const * p
这里不是想讨论常量指针和指针常量,而是想说下char const * p。这里,const修饰的并不是p,而是char,这条语句相当于const char *p。不过从写法上很容易误解,所以最好不要采用这种写法。