协慌网

登录 贡献 社区

类的函数声明中 “const” 最后的含义?

像这样的声明const的含义是什么? const使我感到困惑。

class foobar
{
  public:
     operator int () const;
     const char* foo() const;
};

答案

当您将const关键字添加到方法时, this指针本质上将成为指向const对象的指针,因此您不能更改任何成员数据。 (除非您使用mutable ,稍后再介绍)。

const关键字是函数签名的一部分,这意味着您可以实现两种类似的方法,一种是在对象为const时调用的,另一种不是。

#include <iostream>

class MyClass
{
private:
    int counter;
public:
    void Foo()
    { 
        std::cout << "Foo" << std::endl;    
    }

    void Foo() const
    {
        std::cout << "Foo const" << std::endl;
    }

};

int main()
{
    MyClass cc;
    const MyClass& ccc = cc;
    cc.Foo();
    ccc.Foo();
}

这将输出

Foo
Foo const

在非 const 方法中,您可以更改实例成员,而在const版本中则不能。如果将上面示例中的方法声明更改为下面的代码,则会出现一些错误。

void Foo()
    {
        counter++; //this works
        std::cout << "Foo" << std::endl;    
    }

    void Foo() const
    {
        counter++; //this will not compile
        std::cout << "Foo const" << std::endl;
    }

这不是完全正确的,因为您可以将成员标记为mutable const方法可以对其进行更改。它主要用于内部柜台和东西。解决方案将是下面的代码。

#include <iostream>

class MyClass
{
private:
    mutable int counter;
public:

    MyClass() : counter(0) {}

    void Foo()
    {
        counter++;
        std::cout << "Foo" << std::endl;    
    }

    void Foo() const
    {
        counter++;    // This works because counter is `mutable`
        std::cout << "Foo const" << std::endl;
    }

    int GetInvocations() const
    {
        return counter;
    }
};

int main(void)
{
    MyClass cc;
    const MyClass& ccc = cc;
    cc.Foo();
    ccc.Foo();
    std::cout << "Foo has been invoked " << ccc.GetInvocations() << " times" << std::endl;
}

将输出

Foo
Foo const
Foo has been invoked 2 times

const 表示该方法保证不会更改该类的任何成员。 const ,您也可以执行标记为该对象的成员:

const foobar fb;
fb.foo();

是合法的。

请参见C ++ 中 “const” 的用途是什么?想要查询更多的信息。

const foobar任何值上调用这些方法。当您考虑在 const 对象上调用非 const 方法时,会出现区别。考虑您的foobar类型是否具有以下额外的方法声明:

class foobar {
  ...
  const char* bar();
}

bar()方法是非常量的,只能从非常量值访问。

void func1(const foobar& fb1, foobar& fb2) {
  const char* v1 = fb1.bar();  // won't compile
  const char* v2 = fb2.bar();  // works
}

const背后的想法是标记不会改变类内部状态的方法。这是一个强大的概念,但实际上无法在 C ++ 中执行。它更多的是承诺而不是保证。而且它经常被打破并且很容易被打破。

foobar& fbNonConst = const_cast<foobar&>(fb1);