有没有办法摆脱虚拟成员函数的常量

时间:2011-09-16 14:49:29

标签: c++ virtual-functions const-correctness

我需要为一个定义类似于:

的接口实现模拟
class Foo
{
public:
  void sendEvent(int id) const = 0;
}

我的模拟类需要保存发送给类的所有事件ID。这就是我打算这样做的方式。

class FooMock : Foo
{
private: 
  m_vector std::vector<int>;
public:
  void sendEvent(int id) const {m_vector.push_back(id);}

}

但显然编译器拒绝构造。有没有解决方案(假设界面无法更改)?

我意识到我可以为此使用两个类。但是有没有办法关闭编译器并允许我这样做,类似于const_cast?

4 个答案:

答案 0 :(得分:6)

您可以创建向量mutable,以便可以在const方法中修改它,如下所示:

mutable std::vector<int> m_vector;

但请注意,这使得矢量可以从所有方法变为可变。如果您只想从单个方法写入它,const_cast的侵入性较小,因为您只需为一次调用转换this的常量:

FooMock * const that = const_cast<FooMock * const>(this);
that->m_vector.push_back(id);

我在这里有点迂腐 - 在const方法中,this具有类型T const * const(因此指向的对象以及指针本身都是const)。 const_cast只是抛弃了对象的常量,而不是指针。

答案 1 :(得分:2)

另一种没有mutable的方法(当它不可用时)和const_cast使用指针成员。指责者不遵循常量。

class FooMock : Foo
{
private: 
  boost::scoped_ptr<std::vector<int> > m_vector;
public:
  FooMock() : m_vector(new std::vector<int>) { }
  void sendEvent(int id) const {m_vector->push_back(id);}
}

如果可能的话,我会使用mutable进行嘲弄。

答案 2 :(得分:1)

成员函数的常量是函数签名的部分。你无法摆脱它。

但是,您可以将成员定义为mutable,您希望在const成员函数中 mutate 。即使在const-member函数中,关键字mutable也会使成员可变/可修改,即使对象是const。

答案 3 :(得分:0)

您可以将m_vector标记为mutable

mutable std::vector<int> m_vector;

mutable产生了一些与const_cast类似的争议,它引发了一些关于真正意味着const的理论讨论。基本上只要外部行为保持const状态就可以证明这是合理的,我认为这是真实的看这个例子。