关于C++里const的pitfall

文章主要对MICHAEL PENG(以下称MP)对某开源代码的评价而写。 作者希望给技术讨
论增加一点深度。

MP认为只要“语义const“就必须加上, 比如他的评论

class IRule
{

  public:

  // MichaelPeng: Name函数可以设置为const

  virtual const char* Name(void) = 0;

  ...

};

 

上面是个抽象类(abstract class), 定义了继承类必须实现的方法。我把微软专用
的LPCSTR 改成了对应的const char*, 相信大家都看得懂。

这个函数返回一个“内
容不可修改“的指针, 我这里打上了引号, 根据下面会讲到。

MP认为, 这个函数应该定义为

virtual const char* Name(void) const = 0;

这个我是很同意的。 但是MP在理论时是不是没有看到潜在的问题呢?
假如我已经写了上百个继承类了, 然后我需要要写一个复杂的。我需要去到另一服
务器去拿这个NAME。 为了程序的性能, 我只能在第一次调用的时候去拿

class myRemoteRule : public IRule

{

public:

    myRemoteRule(const char* serverA);

    virtual const char* Name(void) const;

private:

    std::string strName;

    std::string serverAddr;

};

 

const char* myRemoteRule::Name(void) const

{

   if (strName.empty()) {

           strName = getNameFromRemote(serverAddr);

   }

   return strName.c_str();

}

 

然后编译, 结果编译器给了错误。 因为上面的语句里成员strName 被修改了, 函
数不能为CONST。

我已经写了几百个类了, 我得一个一个改回去。 我去翻翻C++的书, 果然有如何
FQ的技术:

const char* myRemoteRule::Name(void) const

{

  if (strName.empty()) {

    const_cast<myRemoteRule*>(this)->strName = getNameFromRemote("rule-server"
);

  }

  return strName.c_str();

}

 

这只是一个小CASE。 实际正常的CLASS都有很多数据成员和函数成员。 如果需要翻
很多墙, 整个CODE 都会充满了const_cast.
实际情况有可能是很复杂的, 看了一个函数的定义就说它一定是const是把世界看
得太简单了。
另外, 说const就能优化也是一种理解错误。 C++书上说const 常数可以直接替代,
以及常数字符串可以优化, const 函数并不能优化。 实际上由于const_cast的存
在, 编译器必须把const指针当成non const, 因为无法预知这是否会修改。 比如:

 

const char* name = rule.Name(); 

... 100 lines later

const_cast<char*>(name)[0] = 'P';

 

这段CODE完全合法。

原文链接: https://www.cnblogs.com/CplusplusExpert/archive/2010/12/02/1894887.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    关于C++里const的pitfall

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/18186

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月7日 下午6:57
下一篇 2023年2月7日 下午6:57

相关推荐