Answers:
阅读此内容:https : //isocpp.org/wiki/faq/const-correctness
最终const意味着功能Method3不会修改其类的非可变成员。
const int* const表示指向常量int的常量指针:即,不能更改的指针,指向不能更改的int指针:和之间的唯一区别在于const int&它可以是null
const int* const&表示对指向常量int的常量指针的引用。通常,指针不通过引用传递。const int* &更有意义,因为这意味着可以在方法调用期间更改指针,这是我看到的通过引用传递指针的唯一原因,const int* const&其所有意图和目的const int* const都与之相同,只是它的效率可能较低由于指针是普通的旧数据(POD)类型,因此通常应按值传递这些类型。
如果将其重写为完全等效的内容,则更容易理解
// 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名为的成员函数,该成员函数Method3引用指向的const指针int const(const int如果需要,可以引用,然后返回const指向的指针int const(const int))。
(Nb#2 完全多余。)
首先const T等于T const。
const int* const因此等于int const * const。
读取其中包含许多const标记和指针的表达式时,请始终尝试从右到左读取它们(应用上面的转换之后)。因此,在这种情况下,返回值是指向constint的const指针。在const这里,使指针本身没有意义,因为返回值不是可以修改的左值。const但是,指定为pointee 可以确保调用者不能修改由其返回的int(或的数组int)Method3。
const int*const&成为int const*const&,因此它是对指向const的const指针int的引用。通过引用传递const指针也没有任何意义-您不能修改引用的值,因为指针为,const并且引用和指针占用相等的存储空间,因此也没有任何空间节省。
最后一个const表示该方法未修改该this对象。this方法主体中的指针将具有(理论上的)声明T const * const this。这意味着一个const T*对象将能够调用T::Method3()。
consts放在短语的开头,那么整个事情就更有意义了。这就是为什么我认为const即使在语言允许的情况下也放在那里是不好的做法,这是最常见的用法。
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 */
我喜欢使用“时钟”或“螺旋”方法,其中从标识符名称(在这种情况下Method3)开始,您从左到右从左到右依次读取等等,以便进行解码命名约定。这样const int* const Method3(const int* const&) const的类方法也不会更改(任何未命名类的)任何类成员,并且对指向常量的指针进行常量引用,int并返回指向常量的常量指针int。
希望这可以帮助,
杰森
在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
const#1:Method3返回的指针指向const int。
const#2:函数本身返回的指针值为const。这是一个无用的const(尽管在语法上是有效的),因为函数的返回值不能为l值。
const#3:通过引用传递给函数的指针类型指向const int。
const#4:通过引用传递给函数的指针值本身就是const指针。将值声明为const传递给函数通常是没有意义的,但是此值是通过引用传递的,因此它可能是有意义的。
const#5:函数(可能是成员函数)是const,这意味着它不允许(a)向对象所属的对象的任何成员分配新值,或者(b)调用非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;
}
};
我希望这有帮助!