Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
你什么时候用过C++';可变的';关键词? 你使用C++ >代码>可变的< /Cord>关键字吗?为什么?我想我从来没有用过那个关键词。我知道它用于缓存(或者记忆)之类的事情,但您在什么类别和条件下需要使用它?_C++ - Fatal编程技术网

你什么时候用过C++';可变的';关键词? 你使用C++ >代码>可变的< /Cord>关键字吗?为什么?我想我从来没有用过那个关键词。我知道它用于缓存(或者记忆)之类的事情,但您在什么类别和条件下需要使用它?

你什么时候用过C++';可变的';关键词? 你使用C++ >代码>可变的< /Cord>关键字吗?为什么?我想我从来没有用过那个关键词。我知道它用于缓存(或者记忆)之类的事情,但您在什么类别和条件下需要使用它?,c++,C++,将是最好的例子。嘿,我今天学到了一些东西 我的模板类实现了引用计数器模式。当它作为带有const修饰符的参数传递给函数时,引用可能会增加。因此,可以使用mutable代替const_cast。在mock对象中捕获成员变量中const函数的参数值 class Source { public: virtual ~Source() {} virtual std::string read(int count) const=0; }; class SourceMock : public

将是最好的例子。嘿,我今天学到了一些东西

我的模板类实现了引用计数器模式。当它作为带有const修饰符的参数传递给函数时,引用可能会增加。因此,可以使用mutable代替const_cast。在mock对象中捕获成员变量中const函数的参数值

class Source
{
public:
    virtual ~Source() {}
    virtual std::string read(int count) const=0;
};

class SourceMock : public Source
{
public:
    mutable std::vector<int> arguments;
    std::string read(int count) const {
        arguments.push_back(count);
        return "...";
    }
};

//TEST....
SourceMock mock;
//...
VERIFY(mock.arguments.size()==2);
VERIFY(mock.arguments[0]==3);
//...
类源代码
{
公众:
虚拟~Source(){}
虚拟标准::字符串读取(整数计数)常量=0;
};
类SourceMock:公共源
{
公众:
可变std::向量参数;
std::字符串读取(整数计数)常量{
参数。推回(计数);
返回“…”;
}
};
//测试。。。。
源模拟;
//...
验证(mock.arguments.size()==2);
验证(模拟参数[0]==3);
//...

偶尔我会使用它将互斥锁或其他线程同步原语标记为可变的,这样通常标记为
const
的访问器/查询方法仍然可以锁定互斥锁

当您需要为调试或测试目的插入代码时,它有时也很有用,因为插入通常需要修改查询方法内部的辅助数据。

揭示了许多用途。例如,在的实现中,使用可变成员,以便方法可以返回对结果的引用(防止复制)


另一个例子是,使用它延迟初始化成员数据(m_lineHeight)。

为了线程安全,我在锁定互斥锁时使用它。互斥锁被标记为可变的,因此锁定互斥锁的方法可以保持常量。

在从内部成员计算对象缓存结果时,我使用了可变的:

class Transformation
{
    private:
        vec3 translation;
        vec3 scale;
        vec4 rotation;
        mutable mat4 transformation;
        mutable bool changed;
    public:
        Node()
        {
            [...]
            changed = false;
        }
        void set_translation(vec3 _translation)
        {
            translation = _translation;
            changed = true;
        }
        void set_scale(...) ...


        mat4 get_transformation() const
        {
            if(changed)
            {
                 // transformation and changed need to be mutable here
                 transformation = f(translation, scale, rotation); // This take a long time...
                 changed = false;
            }
            return transformation;
        }
};

void apply_tranformation(const Transformation* transfo)
{
    apply(transfo->get_transformation());
}

我对按需初始化的类成员使用
mutable
,特别是从程序外部的数据库或源。这允许“getter”函数按需创建对象,否则它是一个常量方法。

它可以在许多场景中使用,例如

记录器
定时
访问计数器


可以在const限定的访问器中调用它们,而无需更改数据的状态。

mutable关键字允许您修改const上下文中的变量

e、 g:

班级人员{
私人:
可变智力;
公众:
个人(年龄):年龄(年龄){
}
无效设置(整数)常数{
人:年龄=年龄;
}
int getAge()常量{
返回人:年龄;
}
};
int main(){
个人(23);

std::cout如果在getter方法中(通常是常量)也可以使用,您需要更新存储的返回值。。例如,假设您有一个特定的链表实现。对于性能问题,您保留列表的最后计算长度,但在返回长度时,如果列表已修改,您将再次计算,否则,您将返回最后缓存的值

class MyLinkedList
{
public:
  long getLength() const
  {
    if (lengthIsModified())
    {
      mLength = ...; // do the computation here
    }
    return mLength;
  }
private:
  mutable long mLength;
};

警告:由于列表中的某些特定操作(如合并),要始终保持MLENGHT最新并非易事。

您的意思是可能重复?尽管看起来很奇怪,但这并不是“记忆”的输入错误@acidzombie24我认为给出的答案在这里非常相关。这就是为什么它可能重复。如果它不是,它将不会被关闭。@acidzombie24请保持它的干净和不褪色-abusive@David赫弗南:保持什么干净?我在编程中不会滥用关键字,所以这个问题:)我可以看出这是多么有用,但我还是想不起什么时候我会这么做uld实际上是这样做的(似乎总是有更好的地方来说明这一点)事实上,我曾多次遇到这种情况:首先设计类,使其getter的一部分为const,然后添加更多的代码,使用从“const Ptr*class::getSomeMember()const;”获得的Ptr在这种情况下,编译器抱怨它“无法在此上下文中使用const Ptr*”或者别的什么。现在我知道如何修复:)链接断开了。+1很酷的情况。我仍然很难想象什么时候会用到它,但我相信这一点。嗯,很有趣。做你的模板比保持你的模板更好吗?这不就解决了吗?+1anyways@acidzombie24-如果内部类真的是const,这是真的,但对于genr所有用途都非常严格。我发现这是我一直使用的代码中最常用的mutable。事实上,我在声明它们时默认使用
mutable mutex
,而从未考虑过该语言是否需要
mutable
关键字。毕竟,
mutex
不是对象的状态。这正是我使用它的主要目的。前提是链接已断开
class MyLinkedList
{
public:
  long getLength() const
  {
    if (lengthIsModified())
    {
      mLength = ...; // do the computation here
    }
    return mLength;
  }
private:
  mutable long mLength;
};