C ++ Const使用说明

const int* const Method3(const int* const&) const; 

有人可以解释每个常量的用法吗?

阅读: https : //isocpp.org/wiki/faq/const-correctness

最后的const意味着函数Method3不会修改它的类的非可变成员。

const int* const表示一个常量指针,指向一个常量int:即一个不能改变的指针,指向一个不能被改变的int:这个和const int&之间的唯一区别const int&是它可以是null

const int* const&表示对常量int的常量指针的引用。 通常指针不是通过引用传递的; const int* &更有意义,因为这意味着指针可以在方法调用期间改变,这将是我可以看到通过引用传递指针的唯一原因, const int* const&是所有意图和目的都是相同的作为const int* const除非指针是普通旧数据(POD)types,效率可能较低,并且通常应该按值传递。

如果将其重写为完全相同,则更容易理解

 // v───v───v───v───v───v───v───v───v───v───v───v─┬┐ // ││ // v──#1 v─#2 v──#3 v─#4 #5 int const * const Method3(int const * const&) const; 

然后从右向左读。

#5表示左边的整个函数声明是const ,这意味着这必然是成员函数而不是自由函数。

#4表示左边的指针是const (不能改变指向不同的地址)。

#3表示左边的intconst (可能不会被更改为具有不同的值)。

#2表示左边的指针是const

#1说左边的intconst

综合起来,你可以把它看作一个名为Method3const成员函数,它接受一个指向一个int constconst指针(或者一个const int ,如果你愿意的话),并返回一个const指针给一个int constconst int )。

首先const T等价于T const

const int* const因此等同于int const * const

当读取有很多const标记和指针的expression式时,总是尝试从右向左读取它们 (应用上面的转换之后)。 所以在这种情况下,返回值是一个const int指针 。 使指针本身成为const是没有意义的,因为返回值不是可以修改的左值。 但是,使pointee为const可以保证调用者不能修改Method3返回的int (或者int的数组)。

const int*const&成为int const*const& ,所以它是对const int的const指针引用 。 通过引用传递一个const指针男性没有任何意义 – 你不能修改引用的值,因为指针是const ,引用和指针占用相同的存储空间,所以没有任何空间节省。

最后一个const表示该方法不修改this对象。 方法体内的this指针将具有(理论上的) T const * const this声明。 这意味着一个const T*对象将能够调用T::Method3()

记住const规则的一个简单的方法就是这样思考: const除了左边没有任何东西外,它适用于左边的东西。

所以在const int * const的情况下,第一个const在它的左边没有任何东西,所以它适用于int ,第二个const在它的左边有一些东西,所以它适用于指针。

这个规则也告诉你在const int const *的情况下会发生什么。 由于这两个const适用于int这个expression式是多余的,因此是无效的。

我喜欢使用“时钟”或“螺旋”方法 ,从标识符名称开始(在本例中是方法Method3 ),您从左到右从后到左来回读取等等解码命名约定。 所以const int* const Method3(const int* const&) const是一个类方法,它不改变任何类成员(一些未命名的类),并接受一个指向常量int的指针的常量引用,并返回一个常量int常量指针。

希望这可以帮助,

贾森

 const /* don't modify the int or array of ints' value(s) */ int* const /* as a retval, ignored. useless declaration */ Method3(const /* don't modify the int or array of ints' value(s) */ int* const /* don't modify the pointer's value, the address to which `pointer` points to. eg you cannot say `++pointer` */ &) const; /* this method does not modify the instance/object which implements the method */ 

从右向左阅读使理解修饰符更容易。

一个const方法,它接受一个const指针的const指针,该指针称为Method3 ,它返回一个const指针的const指针。

  1. const方法不能修改成员(除非它们是明确mutable
  2. 一个const指针不能改变指向别的东西
  3. const int(或任何其他types)不能被修改

const#1:由Method3返回的指针指向一个const int。

const#2:函数返回的指针值本身是const。 这是一个无用的常量(虽然有效),因为函数的返回值不能是l值。

const#3:引用传递给函数的指针types指向一个const int。

const#4:通过引用传递给函数的指针值本身是一个const指针。 声明一个作为const传递给函数的值通常是没有意义的,但是这个值是通过引用传递的,所以它可能是有意义的。

const#5:函数(大概是一个成员函数)是const的,这意味着不允许(a)将新的值赋给它所属的对象的任何成员,或者(b)调用一个非const成员函数对象或其任何成员。

在C ++中记住const的一个简单方法是当你看到如下forms的代码:

 XXX const; const YYY; 

XXX,YYY将是一个不变的组成部分,
XXX const表单:

 function ( def var ) const; ------#1 * const; ------#2 

const YYYforms:

 const int; ------#3 const double; 

人们通常使用这些types。 当你在某个地方看到"const&" ,不要感到困惑,const会在自己之前描述一些东西。 所以现在这个问题的答案是不言而喻的。

 const int* const Method3(const int* const&) const; | | | | | #3 #2 #3 #2 #1 
  • 方法结尾处的const是限定符,表示对象的状态不会被改变。

  • const int*const&表示通过引用接收const指针的常量指针。 它既不能改变指向不同的位置,也不能改变它指向的值。

  • const int*const是返回值,它也是一个指向常量位置的常量指针。

一些例子可能是很好的展示这个概念,越好越好。

 class TestClass { private: int iValue; int* oValuePtr; int& oValueRef; public: int TestClass::ByValMethod1(int Value) { // Value can be modified Value++; // iValue can be modified iValue = Value; iValue += 1; // Return value can be modified return ++iValue; } int TestClass::ByValMethod2(const int Value) { // Value *cannot* be modified // Variable is const variable Value++; // iValue can be modified iValue = Value; iValue += 1; // Return value can be modified return ++iValue; } const int TestClass::ByValMethod3(int Value) { // Value can be modified Value++; // iValue can be modified iValue = Value; iValue += 1; // Return value can be modified return ++iValue; } const int TestClass::ByValMethod4(const int Value) { // Value *cannot* be modified // Variable is const variable Value++; // iValue can be modified iValue = Value; iValue += 1; // Return value can be modified return ++iValue; } const int TestClass::ByValMethod5(const int Value) const { // Value *cannot* be modified // Variable is const variable Value++; // iValue *cannot* be modified // Access through a const object iValue = Value; iValue += 1; // Return value *cannot* be modified // Access through a const object return ++iValue; } int& TestClass::ByRefMethod1(int& Value) { // Value can be modified Value++; // oValueRef can be modified oValueRef = Value; oValueRef += 1; // Return value can be modified return ++oValueRef; } int& TestClass::ByRefMethod2(const int& Value) { // Value *cannot* be modified // Variable is const variable Value++; // oValueRef can be modified oValueRef = Value; oValueRef += 1; // Return value can be modified return ++oValueRef; } const int& TestClass::ByRefMethod3(int& Value) { // Value can be modified Value++; // oValueRef can be modified oValueRef = Value; oValueRef += 1; // Return value can be modified return ++oValueRef; } const int& TestClass::ByRefMethod4(const int& Value) { // Value *cannot* be modified // Variable is const variable Value++; // oValueRef can be modified oValueRef = Value; oValueRef += 1; // Return value can be modified return ++oValueRef; } const int& TestClass::ByRefMethod5(const int& Value) const { // Value *cannot* be modified // Variable is const variable Value++; // oValueRef can be modified oValueRef = Value; oValueRef += 1; // Return value can be modified return ++oValueRef; } int* TestClass::PointerMethod1(int* Value) { // Value can be modified Value++; // oValuePtr can be assigned oValuePtr = Value; // oValuePtr can be modified oValuePtr += 1; // Return value can be modified return ++oValuePtr; } int* TestClass::PointerMethod2(const int* Value) { // Value can be modified Value++; // oValuePtr cannot be assigned // const int* to int* oValuePtr = Value; // oValuePtr can be modified oValuePtr += 1; // Return value can be modified return ++oValuePtr; } const int* TestClass::PointerMethod3(int* Value) { // Value can be modified Value++; // oValuePtr can be assigned oValuePtr = Value; // iValue can be modified oValuePtr += 1; // Return value can be modified return ++oValuePtr; } const int* TestClass::PointerMethod4(const int* Value) { // Value cannot be modified Value++; // oValuePtr *cannot* be assigned // const int* to int* oValuePtr = Value; // oValuePtr can be modified oValuePtr += 1; // Return value can be modified return ++oValuePtr; } const int* TestClass::PointerMethod5(const int* Value) const { // Value can be modified ++Value; // oValuePtr *cannot* be assigned // const int* to int* const // Access through a const object oValuePtr = Value; // oValuePtr *cannot* be modified // Access through a const object oValuePtr += 1; // Return value *cannot* be modified return ++oValuePtr; } }; 

我希望这有帮助!

我只想提到const int* const&确实是一个const int*的常量引用。 例如:

 int i = 0; int j = 1; int* p = &i; int* q = &j; const int* const& cpref = p; cpref = q; //Error: assignment of read-only reference 'cpref' 

int* const&也是这种情况,这意味着:“对int*常量引用”。
但是const int*&const int*&的一个非常量引用。
希望这可以帮助。