有没有办法摆脱虚成员函数的constness ?

Is there a way to get rid of constness of virtual member functions

本文关键字:函数 constness 成员 有没有      更新时间:2023-10-16

我需要实现一个接口的模拟,其定义如下:

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?

您可以将向量mutable设置为可以在const方法中进行修改,如下所示:

mutable std::vector<int> m_vector;
但是要注意,这使得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只是抛弃了对象的常量,而不是指针的常量。

另一个没有可变(当不可用时)和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来模拟

成员函数的const-ness 是函数签名的一部分。你不能摆脱它。

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

可以将m_vector标记为mutable:

mutable std::vector<int> m_vector;

mutableconst_cast产生了一些类似的争议,它导致了一些关于真正的const的理论讨论。基本上,只要外部行为保持const-like,这里就可以证明它是合理的,从这个例子中我假设这是正确的。