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()
。
const
s放在短语的开头,那么整个事情就更有意义了。这就是为什么我认为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;
}
};
我希望这有帮助!