关于C++的建议,仅仅为了规范代码(二)

参考的Andrey Karpov的<<C++编程的 42 条建议>>

11.单是文件终止符(EOF)的检查还不够。

有时候‘cin.eof()’这个条件不够。考虑加‘cin.fail()’这一函数调用到条件表达式中。

template <typename T>
std::istream &operator >>(std::istream &i, sqlblob<T> &b) 
{
    
    
 ....
 while (!i.eof()) 
 {
    
    
 i >> tmp;
 buf+=(tmp+' ');
 }
 ....
}

解释:用eof()来检查文件结束不是充分条件,而且你无法确定是否出现了读取错误或者流出错,这两个都会引起特定的问题。如果有任何数据读取错误,就会导致无限循环,因为eof()总返回 false。这个在循环种可能会造成死循环。所以我们要用bad(), fail()来查询流状态。

建议:当用流来读取数据的时候,不要只使用 eof(),还要检查其他故障。 使用 bad() 和 fail()函数来检查流的状态。第一个函数是用来流的完整性,第二个函数是用来检查数据读取错误的。但是,用 bool()操作会更便捷一些,就像在正确代码那里显示的。

例子:

template <typename T>
std::istream &operator >>(std::istream &i, sqlblob<T> &b) 
{
    
    
 ....
 while (i >> tmp) 
 {
    
    
 buf+=(tmp+' ');
 }
 ....
}

12.自动计算字符串长度。

例如:

else if (!strncmp(vstart, "HEX", 3))

之后,用"BITLIST"代替"HEX" ,但是程序员忘了把 3 改为 7. 结果就是,字符串不是和"BITLIST"做比较,而是仅仅比较了"BIT"。这个错误似乎不太严重,但终究是个错误。
修改:

else if (!strncmp(vstart, "BITLIST", strlen("BITLIST")))

用strlen(“BITLIST”)会比较好
但这样是有缺点的:

  • 无法保证编译器会不会优化 strlen()调用:用一个常数来代替它。
  • 你要逐字复制字符串。看上去不好看,而且也会出错。
    在C++中我们可以用模板,我个人不喜欢用宏:
template<typename T, size_t N>
int mystrncmp(const T *a, const T (&b)[N])
{
    
    
 return _tcsnccmp(a, b, N - 1);
}

13.学会使用Override 和 final 标识符。

用了这两个标识符,对重写函数有帮助。

  • Override——表明该函数是重写基类中的虚函数。
  • Final——表明该函数在派生类中无需重写。
    例子:
class CFrameWndEx : public CFrameWnd {
    
    
 ....
 virtual void WinHelp(DWORD_PTR dwData,
 UINT nCmd = HELP_CONTEXT) override;
 ....
};

14.不要再拿‘this’和 nullptr 比较。

根据现代 C++标准,this 永远不会等于 nullptr。

15.用 nullptr 不要用 NULL。

猜你喜欢

转载自blog.csdn.net/weixin_45743162/article/details/109549496
今日推荐