C ++方法声明中最后一个“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方法可以更改它。 它主要用于内部计数器和东西。 解决scheme将是下面的代码。

 #include <iostream> class MyClass { private: mutable int counter; public: MyClass() : counter(0) {} void Foo() { counter++; std::cout << "Foo" << std::endl; } void Foo() const { counter++; 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 << "The MyClass instance has been invoked " << ccc.GetInvocations() << " times" << endl; } 

这将输出

 Foo Foo const The MyClass instance has been invoked 2 times 

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

 const foobar fb; fb.foo(); 

将是合法的。

请参阅C ++中“const”的用法和使用方法? 了解更多信息。

const限定符意味着可以在foobar任何值上调用方法。 当你考虑在一个const对象上调用一个非const方法的时候,会有所不同。 考虑如果你的foobartypes有以下额外的方法声明:

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

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

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

这些常量意味着编译器将错误,如果方法“与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 } 

阅读此以获取更多信息

布莱尔的回答是关键的。

但是请注意,有一个mutable限定符可以被添加到类的数据成员。 如此标记的任何成员可以在不违反const约定的情况下在const方法中进行修改。

如果你想要一个对象记住一个特定方法被调用的次数,而不影响该方法的“逻辑”常量,你可能想要使用它(例如)。

当你在方法签名中使用const (就像你所说的: const char* foo() const; ),你告诉编译器这个指向的内存不能被这个方法改变(这里是foo )。

C ++ 常量成员函数的含义 常识:基本中级编程给出了一个清晰的解释:

这个指针在类X的非const成员函数中的types是X * const。 也就是说,它是一个指向非常数X的常量指针(参见Const指针和指向Const的指针[7,21])。 因为这个引用的对象不是const的,所以它可以被修改。 这个在类X的const成员函数中的types是const X * const。 也就是说,它是一个指向常量X的常量指针。因为这个引用的对象是const,所以它不能被修改。 这是const和非const成员函数的区别。

所以在你的代码中:

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

你可以这样想:

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