简体   繁体   English

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

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

I need to implement a mock for an interface that is defined something like: 我需要为定义如下的接口实现一个模拟:

class Foo
{
public:
  void sendEvent(int id) const = 0;
}

My mock class needs to save all event id's sent to the class. 我的模拟类需要保存发送给该类的所有事件ID。 This is how I intended to do it. 这就是我打算这样做的方式。

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

}

But obviously the compiler refuses that construction. 但是显然编译器拒绝该构造。 Are there any solutions to this (assuming the interface could not be changed)? 有什么解决方案(假设接口无法更改)?

I realize that I can use two classes for this. 我意识到我可以为此使用两个类。 But isn't there a way to shut the compiler up and allow me to to this, similar to const_cast? 但是没有办法像const_cast那样关闭编译器并允许我这样做吗?

You can make the vector mutable so that it can be modified from within const methods, like this: 您可以使向量mutable以便可以从const方法中对其进行修改,如下所示:

mutable std::vector<int> m_vector;

Note however that this makes the vector mutable from all methods. 但是请注意,这使得向量对所有方法都是可变的。 If you only want to write to it from a single method, a const_cast is less invasive, in that you cast the constness of this away just for a single call: 如果你只想从一个单一的方法写,一个const_cast是微创的,因为你施放的常量性this仅有单个呼叫:

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

I'm being a bit pedantic here - inside a const method, this has the type T const * const (so both the object being pointed to as well as the pointer itself are const). 我在这里有点书呆子-在const方法中, this的类型为T const * const (因此,指向的对象以及指针本身都是const)。 The const_cast just casts away the constness of the object, but not of the pointer. const_cast只是舍弃了对象的常量,而不是指针的常量。

Another method without mutable (when that is not available) and const_cast is using pointer-members. 另一种没有可变(如果不可用)和const_cast的方法是使用指针成员。 The pointees don't follow the constness. 指示者不遵循常态。

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);}
}

When possible, I would use mutable for mocking. 如果可能,我将使用mutable进行模拟。

const-ness of a member-function is a part of the function signature. 成员函数的恒定性是函数签名的一部分 You cannot get rid of it. 你不能摆脱它。

However, you can define the member as mutable , which you want to mutate in a const member function. 但是,您可以将成员定义为mutable ,要在const成员函数中对其进行突变 The keyword mutable would make the member mutable/modifiable even in a const-member function and even if the object is const. 即使在const成员函数中,即使对象是const,关键字mutable也会使成员可变/可修改。

You could mark m_vector as mutable : 您可以将m_vector标记为mutable

mutable std::vector<int> m_vector;

mutable generates a bit of controversy similar to const_cast , and it results in a bit of a theoretical discussion about what it really means to be const . const_cast类似, mutable产生了一些争议,并引起了关于const 真正含义的理论讨论。 Basically it would be justified here as long as the external behavior remains const-like, which I assume is true looking at this example. 基本上,只要外部行为保持类似const,这在这里是合理的,我认为在此示例中是正确的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM