C++ '的含义;常数';类的函数声明中的最后一个?

C++ '的含义;常数';类的函数声明中的最后一个?,c++,constants,declaration,c++-faq,C++,Constants,Declaration,C++ Faq,在这样的声明中,const的含义是什么?const把我弄糊涂了 class foobar { public: operator int () const; const char* foo() const; }; const意味着该方法承诺不会更改类的任何成员。即使对象本身被标记为const,您也可以执行这样标记的对象成员: const foobar fb; fb.foo(); 这是合法的 有关更多信息,请参阅。这些常量意味着,如果“with const”方法更改内部数

在这样的声明中,
const
的含义是什么?
const
把我弄糊涂了

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

const意味着该方法承诺不会更改类的任何成员。即使对象本身被标记为
const
,您也可以执行这样标记的对象成员:

const foobar fb;
fb.foo();
这是合法的


有关更多信息,请参阅。

这些常量意味着,如果“with const”方法更改内部数据,编译器将出错

class A
{
public:
    A():member_()
    {
    }

    int hashGetter() const
    {
        state_ = 1;
        return member_;
    }
    int goodGetter() const
    {
        return member_;
    }
    int getter() const
    {
        //member_ = 2; // error
        return member_;
    }
    int badGetter()
    {
        return member_;
    }
private:
    mutable int state_;
    int member_;
};
测试

int main()
{
    const A a1;
    a1.badGetter(); // doesn't work
    a1.goodGetter(); // works
    a1.hashGetter(); // works

    A a2;
    a2.badGetter(); // works
    a2.goodGetter(); // works
    a2.hashGetter(); // works
}

阅读以了解更多信息限定符
const
表示可以对
foobar
的任何值调用这些方法。当您考虑在const对象上调用非const方法时,不同之处就出现了。考虑一下你的<代码> FoBOAR 类型是否有以下额外的方法声明:

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);
foobar&fbNonConst=const_cast(fb1);

布莱尔的答案是正确的

但是请注意,有一个
mutable
限定符可以添加到类的数据成员中。这样标记的任何成员都可以在
const
方法中修改,而不会违反
const
合同


例如,如果您想让对象记住某个特定方法被调用了多少次,同时又不影响该方法的“逻辑”常数,那么您可能需要使用此选项。

当您将
const
关键字添加到某个方法时,
指针实质上将成为指向
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();
}
在non-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;
    }
哪个会输出

Foo
Foo const
Foo has been invoked 2 times

当您在方法签名中使用
const
(如您所说:
const char*foo()const;
)时,您告诉编译器此
指向的内存不能通过此方法更改(此处为
foo
)。

中const成员函数的含义给出了明确的解释:

类的非常量成员函数中此指针的类型 X是X*const。也就是说,它是指向非常量X的常量指针 (参见常量指针和指向常量的指针[7,21])。因为这个物体 它所指的不是常量,可以修改。类型 类X的const成员函数中的值为const X*const。那个 它是一个指向常数X的常数指针。因为 它引用的是常量,不能修改。这就是问题所在 常量和非常量成员函数之间的差异

因此,在您的代码中:

class foobar
{
  public:
     operator int () const;
     const char* foo() const;
};
你可以这样想:

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

我想补充以下几点

您还可以将其设置为
const&
const&

所以

结构{
void val1()常量{
//*此处为常量。因此此函数无法修改*的任何成员
}
void val2()常量和{
//*这里是康斯特&这里
}
void val3()常量&&{
//调用此函数的对象应仅为常量值。
}
void val4(){
//调用此函数的对象应仅为右值引用。
}
};
int main(){
s a;
a、 val1();//好的
a、 val2();//好的
//a.val3()不正常,a不正确如果像这样调用,则值可以正常
std::move(a).val3();//好的,move使其成为右值
}

请随意改进答案。我不是专家

与函数声明一起使用的const关键字指定它是一个const成员函数,它将无法更改对象的数据成员。

什么是“
const
成员函数”? 检查(而不是变异)其对象的成员函数

const
成员函数由成员函数参数列表后面的
const
后缀表示。带有
const
后缀的成员函数称为“const成员函数”或“inspector”。没有
const
后缀的成员函数称为“non-const成员函数”或“mutators”

class Fred {
public:
  void inspect() const;   // This member promises NOT to change *this
  void mutate();          // This member function might change *this
};
void userCode(Fred& changeable, const Fred& unchangeable)
{
  changeable.inspect();   // Okay: doesn't change a changeable object
  changeable.mutate();    // Okay: changes a changeable object
  unchangeable.inspect(); // Okay: doesn't change an unchangeable object
  unchangeable.mutate();  // ERROR: attempt to change unchangeable object
}
试图调用
unchangeable.mutate()
是在编译时捕获的错误。对于
const
,没有运行时空间或速度损失,并且您不需要编写测试用例来在运行时检查它

inspect()
成员函数的尾部
const
应用于表示该方法不会更改对象的抽象(客户端可见)状态。这与说该方法不会改变对象结构的“原始位”略有不同。C++编译器不允许采用“按位”解释,除非它们可以解决通常不能解决的混叠问题(即,存在一个可以修改对象状态的非conas别名)。从这个别名问题中得到的另一个(重要)见解是:用指向const的指针指向一个对象并不能保证该对象不会改变;它仅仅承诺对象不会通过该指针改变


这里const表示在该函数中,任何变量的值都不能更改

class Test{
private:
    int a;
public:
    void test()const{
        a = 10;
    }
};
一个
class Fred {
public:
  void inspect() const;   // This member promises NOT to change *this
  void mutate();          // This member function might change *this
};
void userCode(Fred& changeable, const Fred& unchangeable)
{
  changeable.inspect();   // Okay: doesn't change a changeable object
  changeable.mutate();    // Okay: changes a changeable object
  unchangeable.inspect(); // Okay: doesn't change an unchangeable object
  unchangeable.mutate();  // ERROR: attempt to change unchangeable object
}
class Test{
private:
    int a;
public:
    void test()const{
        a = 10;
    }
};