这对const来说是不可变的吗?

Ide*_*Hat 8 c++ const mutable

基本上,我有以下情况.注意:void*用于表示任意数据,它在实际应用程序中强类型.

class A
{
public:
   //uses intermediate buffer but doesn't change outward behavior
   //intermediate buffer is expensive to fill
   void foo(void* input_data);

   //uses intermediate buffer and DOES explicitly change something internally
   //intermediate buffer is expensive to fill
   void bar(void* input_data);

   //if input_data hasn't changed since foo, we can totally reuse what happened in foo
   //I cannot check if the data is equal quickly, so I allow the user to pass in the
   //assertion (put the honerous on them, explicitly tell them in the comments
   //that this is dangerous to do, ect)
   void bar(void* input_data, bool reuse_intermediate);
private:
   void* intermediate_buffer_;
   void* something_;
};
Run Code Online (Sandbox Code Playgroud)

因此,尝试const正确性时,middle_buffer_永远不会暴露,因此它适合使用mutable变量的定义.如果我从不重用这个缓冲区,或者我在使用缓存值之前检查了相等的input_data,那将是故事的结束,但是由于reuse_intermediate我觉得我有一半暴露它,所以我不确定是否或不是以下有意义.

class A
{
public:
   //uses intermediate buffer but doesn't change something
   //intermediate buffer is expensive to fill
   void foo(void* input_data) const;

   //uses intermediate buffer and DOES explicitly change something internally
   //intermediate buffer is expensive to fill
   void bar(void* input_data);

   //if input_data hasn't changed since foo, we can totally reuse what happened in foo
   //I cannot check if the data is equal quickly, so I allow the user to pass in the
   //assertion (put the honerous on them, explicitly tell them in the comments
   //that this is dangerous to do, ect)
   void bar(void* input_data, bool reuse_intermediate);

   //an example of where this would save a bunch of computation, though
   //cases outside the class can also happen
   void foobar(void* input_data)
   {
      foo(input_data);
      bar(input_data,true);
   }
private:
   mutable void* intermediate_buffer_;
   void* something_;
};
Run Code Online (Sandbox Code Playgroud)

思考?

And*_*ndy 6

我认为这是不当使用的mutable.根据我的经验mutable,用于辅助私有成员变量,它们本质上不能声明为const,但不要修改公共接口的"概念常量".

以Mutex成员变量和'线程安全getter'为例:

class Getter { 
public: 

    Getter( int d, Mutex & m ) : guard_( m ), data_( d ) { };

    int get( ) const { Lock l(guard_); return data_; };

private:

    mutable Mutex guard_;
    const int data_;
};
Run Code Online (Sandbox Code Playgroud)

这里的要点是声明的数据mutable(在本例中为guard)确实发生了变化(它被锁定和解锁),但从用户的角度来看这对constness没有影响. 最终,尽管有可变的互斥锁,但仍然无法更改const data_成员变量,编译器会强制执行此操作.

在你的情况下,你真的希望intermediate_buffer是const,但你明确告诉编译器它不是通过声明它是可变的.结果是您可以更改数据,编译器无法对其进行任何操作.

看到不同?

如果您真的希望接口符合const协议,请通过以下方式明确说明:

    class A { 
    public:    

        A( void* input_data );// I assume this deep copies.

        void foo() const;

        void bar();

        private:    
            const void* intermediate_buffer_;   
            void* something_; 
    };
Run Code Online (Sandbox Code Playgroud)

现在,责任真正在用户身上,并由编译器强制执行,无论注释说什么,也不使用任何可变的.如果他们知道input_data已经改变,他们将不得不创建一个新的,最好是const.