const int* const Method3(const int* const&) const;
有人可以解释每个const的用法吗?
答案 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表示左侧的int
为const
(可能不会更改为具有不同的值)。
#2表示左边的指针是const
。
#1表示左侧的int
为const
。
将所有内容放在一起,您可以将其视为名为const
的{{1}}成员函数,该函数引用指向Method3
的{{1}}指针(或{ {1}},如果您愿意,并返回指向const
(int 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指针。
mutable
)答案 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;
}
};
我希望这有帮助!