近期, 工作中遇到类似以下的奇怪代码:
bool ClassName::IsEmpty() {
return (this == NULL || /*其他条件*/);
}
百思不得其解, 并在没有询问任何人的情况下, 将this==NULL去掉, 将代码改为:
bool ClassName::IsEmpty() {
return (/*其他条件*/);
}
就在昨天, 程序总是在某些地方莫名其妙地core. 最后, 一位资深的同事(我入职时的指导老师, 技术和业务能力非常受大家尊敬)定位到问题, 并找到我, 希望把这段代码回退, 听完他的下面两个理由后, 我照做了:
1. 调用这里的NULL->IsEmpty()不会导致程序core
2. 由于程序对ClassName* GetClassPointer()函数进行了改造, 之前不会返回NULL, 但是现在会返回NULL. 代码中充斥着大量如下的代码(改造这些代码的代价太高):
ClassName* p=GetClassPointer();
if (p->IsEmpty())
/*other codes*/
虽然问题是解决了, 内心却许久不能平静, 同时在IsEmpty函数前面写了五行注释, 用以说明原因, 并写下"TO DO", 期待将来抽出时间彻底改造这个问题. 其实回退这段代码而不是改造对IsEmpty函数返回值的错误使用, 也存在个人的私心: 这种用法还是第一次见过呢, 想多多实践, 因为有时候怀疑它真的不会core吗? 这件事情让我对人生产生了思考: 做事情没有标准, 也不可能达到皆大欢喜, 关键是找到一个平衡点.
注: 遵循以下几点, NULL->成员函数不会core:
1. 成员函数不是虚函数
2. 当this为NULL时, 不访问成员变量
下面是一个测试结果:
class C {
public:
void f() {}
int h() { return i; }
int h1() { if (!this) return 0; return i; }
virtual void g() {}
private:
int i;
};
int main()
{
C* pC = NULL;
pC->f(); //不core
pC->h(); //core, 访问了this.i
pC->h1(); //不core
pC->g(); //core
return 0;
}