因此,可以证明const指针高度适用的示例。假设您有一个内部带有动态数组的类,并且希望将用户访问权传递给该数组,但又不授予他们更改指针的权利。考虑:
#include <new>
#include <string.h>
class TestA
{
private:
char *Array;
public:
TestA(){Array = NULL; Array = new (std::nothrow) char[20]; if(Array != NULL){ strcpy(Array,"Input data"); } }
~TestA(){if(Array != NULL){ delete [] Array;} }
char * const GetArray(){ return Array; }
};
int main()
{
TestA Temp;
printf("%s\n",Temp.GetArray());
Temp.GetArray()[0] = ' '; //You can still modify the chars in the array, user has access
Temp.GetArray()[1] = ' ';
printf("%s\n",Temp.GetArray());
}
产生:
输入数据
放置数据
但是,如果我们尝试这样做:
int main()
{
TestA Temp;
printf("%s\n",Temp.GetArray());
Temp.GetArray()[0] = ' ';
Temp.GetArray()[1] = ' ';
printf("%s\n",Temp.GetArray());
Temp.GetArray() = NULL; //Bwuahahahaa attempt to set it to null
}
我们得到:
错误:左值必须作为赋值的左操作数// Drat再次被挫败!
所以很明显,我们可以修改数组的内容,但不能修改数组的指针。如果希望在将指针传递回用户时确保指针具有一致的状态,则很好。但是有一个问题:
int main()
{
TestA Temp;
printf("%s\n",Temp.GetArray());
Temp.GetArray()[0] = ' ';
Temp.GetArray()[1] = ' ';
printf("%s\n",Temp.GetArray());
delete [] Temp.GetArray(); //Bwuahaha this actually works!
}
即使我们不能修改指针本身,我们仍然可以删除指针的内存引用。
因此,如果您希望内存引用始终指向某个内容(IE永远都不会被修改,类似于引用当前的工作方式),那么它非常适用。如果您希望用户具有完全访问权限并对其进行修改,那么非常量适合您。
编辑:
在注意到由于GetArray()是一个右值操作数而无法分配okorz001注释后,他的注释完全正确,但是如果您要返回对指针的引用,以上注释仍然适用(我想我假设GetArray是引用参考),例如:
class TestA
{
private:
char *Array;
public:
TestA(){Array = NULL; Array = new (std::nothrow) char[20]; if(Array != NULL){ strcpy(Array,"Input data"); } }
~TestA(){if(Array != NULL){ delete [] Array;} }
char * const &GetArray(){ return Array; } //Note & reference operator
char * &GetNonConstArray(){ return Array; } //Note non-const
};
int main()
{
TestA Temp;
Temp.GetArray() = NULL; //Returns error
Temp.GetNonConstArray() = NULL; //Returns no error
}
将在第一个中返回并导致错误:
错误:分配只读位置'Temp.TestA :: GetArray()'
但是,尽管可能会对下面的情况造成不利影响,但第二次却是欢乐的。
显然,将提出一个问题:“为什么要返回对指针的引用”?在极少数情况下,您需要直接将内存(或数据)分配给相关的原始指针(例如,构建自己的malloc / free或new / free前端),但在这些情况下,这是一个非常量引用。对const指针的引用我还没有遇到可以保证使用它的情况(除非声明为const引用变量而不是返回类型?)。
考虑一下我们是否有一个使用const指针的函数(与不使用const指针的函数相比):
class TestA
{
private:
char *Array;
public:
TestA(){Array = NULL; Array = new (std::nothrow) char[20]; if(Array != NULL){ strcpy(Array,"Input data"); } }
~TestA(){if(Array != NULL){ delete [] Array;} }
char * const &GetArray(){ return Array; }
void ModifyArrayConst(char * const Data)
{
Data[1]; //This is okay, this refers to Data[1]
Data--; //Produces an error. Don't want to Decrement that.
printf("Const: %c\n",Data[1]);
}
void ModifyArrayNonConst(char * Data)
{
Data--; //Argh noo what are you doing?!
Data[1]; //This is actually the same as 'Data[0]' because it's relative to Data's position
printf("NonConst: %c\n",Data[1]);
}
};
int main()
{
TestA Temp;
Temp.ModifyArrayNonConst("ABCD");
Temp.ModifyArrayConst("ABCD");
}
const中的错误因此产生消息:
错误:只读参数“ Data”的减量
这样做很好,因为我们可能不想这样做,除非我们要引起注释中指出的问题。如果我们在const函数中编辑减量,则会发生以下情况:
非常量:A
常量:B
显然,即使A是“ Data [1]”,也将其视为“ Data [0]”,因为NonConst指针允许进行减量操作。正如其他人所写,实现const后,我们在潜在错误发生之前就将其捕获。
另一个主要考虑因素是,可以将const指针用作伪引用,因为该引用指向的内容无法更改(一个人想知道,也许这是如何实现的)。考虑:
int main()
{
int A = 10;
int * const B = &A;
*B = 20; //This is permitted
printf("%d\n",A);
B = NULL; //This produces an error
}
尝试编译时,产生以下错误:
错误:分配只读变量“ B”
如果要不断引用A,那可能是一件坏事。如果B = NULL
被注释掉,编译器会很乐意让我们修改*B
,因此对A进行。这对于ints似乎没有用,但请考虑您是否对图形应用程序有单一的立场,希望在其中使用一个不可修改的指针来引用它,然后再传递给它。周围。
它的用法是可变的(例如,意外的双关语),但是用法正确,它是包装盒中另一个有助于编程的工具。