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表示左边的int
是const
(可能不会被更改为具有不同的值)。
#2表示左边的指针是const
。
#1说左边的int
是const
。
综合起来,你可以把它看作一个名为Method3
的const
成员函数,它接受一个指向一个int const
的const
指针(或者一个const int
,如果你愿意的话),并返回一个const
指针给一个int const
( const 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指针。
- const方法不能修改成员(除非它们是明确
mutable
) - 一个const指针不能改变指向别的东西
- 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 YYY
forms:
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*&
的一个非常量引用。
希望这可以帮助。