从非const对象调用const函数

Chr*_*ris 21 c++ const function

我需要从非const对象调用const函数.见例子

struct IProcess {
   virtual bool doSomeWork() const = 0L;
};
class Foo : public IProcess {    
  virtual bool doSomeWork() const {
    ...
  }
};

class Bar
{
public:
   const IProcess& getProcess() const {return ...;}
   IProcess& getProcess() {return ...;}

   void doOtherWork {
    getProcess().doSomeWork();        
  }
};
Run Code Online (Sandbox Code Playgroud)

调用

getProcess().doSomeWork();
Run Code Online (Sandbox Code Playgroud)

总是会打电话给

IProcess& getProcess()
Run Code Online (Sandbox Code Playgroud)

还有另一种方式来打电话

const IProcess& getProcess() const 
Run Code Online (Sandbox Code Playgroud)

来自非常数成员函数?我到目前为止使用过

const_cast<const Bar*>(this)->getProcess().doSomeWork();
Run Code Online (Sandbox Code Playgroud)

这样做的技巧,但似乎过于复杂.


编辑:我应该提到代码正在重构,最终只剩下一个函数.

const IProcess& getProcess() const 
Run Code Online (Sandbox Code Playgroud)

但是,目前存在副作用,并且const调用可能在某些时候返回不同的IProcess实例.

请继续主题.

mfa*_*kas 14

const_cast是为了抛弃常数!

你从非const转换为const是安全的,所以使用static_cast:

   static_cast<const Bar*>(this)->getProcess().doSomeWork();
Run Code Online (Sandbox Code Playgroud)

我的意思是说从技术上说你可以用常量来表达const_cast,但这并不是对运算符的务实使用.新风格演员(与旧的C风格演员阵容相比)的目的是传达演员的意图.const_cast是一种代码气味,它的使用至少应该被审查.static_cast另一方面是安全的.但这是C++风格的问题.

或者您可以创建一个新的(私有)const方法,并从doOtherWork以下方法调用:

  void doSomeWorkOnProcess() const { getProcess().doSomeWork(); }
Run Code Online (Sandbox Code Playgroud)

使用const临时也是一个选项(由"MSN"回答):

   const Bar* _this = this;
   _this->getProcess().doSomeWork();
Run Code Online (Sandbox Code Playgroud)

  • 是的,但是mfazekas的观点是你只需要**const_cast <>来删除constness,因为使用"最小的武器来完成这项工作"(即static_cast <>),这符合你自己的利益,因为这样所有出现的const_cast都是代码味道,可以很容易地进行渲染. (5认同)
  • 你实际上可以安全地做到这两点 - 抛弃并施放常量. (2认同)

MSN*_*MSN 10

避免强制转换:将其分配给一个const Bar *或任何东西并使用它来调用getProcess().

这样做有一些迂腐的理由,但它也使得你在做什么而不强迫编译器做一些可能不安全的事情.当然,你可能永远不会遇到这种情况,但你也可以写一些在这种情况下不使用强制转换的东西.

  • 你说的迂腐理由是什么?我原以为一个丑陋的演员会让你的意图比对一个const Bar*的任务更清楚,但这只是我的观点. (3认同)

j_r*_*ker 5

如果强制转换对您来说太难看,您可以改为添加一个方法,Bar该方法只返回对 的 const 引用*this

Bar const& as_const() const {
    return *this;    // Compiler adds "const" without needing static_cast<>
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以通过添加来调用任何 const方法,例如:Baras_const().

as_const().getProcess().doSomeWork();
Run Code Online (Sandbox Code Playgroud)