C ++ Const用法解释

时间:2011-04-08 17:33:34

标签: c++ const

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

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

12 个答案:

答案 0 :(得分:99)

如果将其重写为完全等效的

,则更容易理解
// 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

将所有内容放在一起,您可以将其视为名为const的{​​{1}}成员函数,该函数引用指向Method3的{​​{1}}指针(或{ {1}},如果您愿意,并返回指向constint const)的const int指针。

(N.b。#2 is entirely superfluous。)

答案 1 :(得分:71)

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

最终const表示函数Method3不会修改其类的非可变成员。

const int* const表示一个指向常量int的常量指针:即一个无法更改的指针,指向一个无法更改的int:它与const int&之间的唯一区别是它可以是{ {1}}

null表示对常量int的常量指针的引用。通常指针不通过引用传递; const int* const&更有意义,因为它意味着在方法调用期间可以更改指针,这是我可以看到通过引用传递指针的唯一原因,const int* &是所有意图和目的与const int* const&相同,不同之处在于它可能效率较低,因为指针是普通旧数据(POD)类型,这些通常应该通过值传递。

答案 2 :(得分:22)

首先const T相当于T const

因此,

const int* const相当于int const * const

在阅读包含大量const代币和指针的表达式时,请始终尝试从右到左阅读(在应用上述转换后)。因此,在这种情况下,返回值是指向const int const指针。由于返回值不是可以修改的左值,因此使指针本身const没有任何意义。但是,设置指针const可以保证调用者不会修改int返回的int(或Method3数组)。

const int*const&变为int const*const&,因此它是对指向const int 的const指针的引用。通过引用传递const指针也没有任何意义 - 您无法修改引用的值,因为指针是const,引用和指针占用相同的存储空间,因此也没有任何空间节省。

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

答案 3 :(得分:12)

记住const规则的一种简单方法是以这种方式思考:const适用于其左侧的内容,除非其左侧没有任何内容。

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

此规则还会告诉您在const int const *的情况下会发生什么。由于这两个const都适用于int,因此该表达式是多余的,因此无效。

答案 4 :(得分:3)

我喜欢使用"clock" or "spiral" method从标识符名称开始(在本例中为Method3),您从左到右,从左到右等来回读取,等等。为了解码命名约定。所以const int* const Method3(const int* const&) const是一个类方法,不会更改任何类成员(某些未命名的类),并对指向常量int的指针进行常量引用,并返回一个常量指针常数int

希望这有帮助,

杰森

答案 5 :(得分:2)

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. e.g. you cannot say `++pointer` */
&) const; /* this method does not modify the instance/object which implements the method */

答案 6 :(得分:2)

在C ++中记住const的一种简单方法是在表单中看到一些代码:

XXX const;
const YYY;

XXX,YYY将是一个恒定的组成部分,
XXX const形式:

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

const YYY表格:

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

人们通常使用这些类型。当你在某个地方看到"const&"时,不要感到困惑,const正在描述一些事情。 所以现在这个问题的答案是不言而喻的。

const int* const Method3(const int* const&) const;
  |          |             |          |       |
  #3         #2            #3         #2      #1

答案 7 :(得分:1)

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

一个const方法,它引用一个名为Method3的const int的const指针,它返回一个指向const int的const指针。

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

答案 8 :(得分:1)

const#1:Method3返回的指针引用了一个const int。

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

const#3:通过引用函数传递的指针类型指向const int。

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

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

答案 9 :(得分:1)

我只想提一下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*的非常量引用 希望这可以帮助。

答案 10 :(得分:0)

    方法结尾处的
  • const是限定符,表示对象的状态不会被更改。

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

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

答案 11 :(得分:0)

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

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

我希望这有帮助!