我需要为一个定义类似于:
的接口实现模拟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?
答案 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状态就可以证明这是合理的,我认为这是真实的看这个例子。