1、声明指向指针的指针是合法。这就是C++标准所说的“多级”指针。
int *pi;
int **ppi;
int ***pppi; //一个多级(3级)指针
2、第一种情形:声明一个指针数组时;
Shape *picture[ MAX ]; //一个数组,其元素为指向Shape的指针
由于数组的名字会退化为指向其首元素的指针,所以指针数组的名字也是一个指向指针的指针。
Shape **pic1 = picture;
我们在管理指针缓冲区的类的实现中常见到这种用法:
template <typename T>
class PtrVector
{
public:
explicit PtrVector(size_t capacity) : buf_(new T *[capacity]), cap_(capacity), size_(0)) { }
//.....
private:
T **buf_; //一个指针,指向一个数组,该数组元素为指向T的指针
size_t cap_; //容量
size_t size_; //大小
};
//.....
PtrVector<Shape> pic2(MAX);
3、第二个应用情形:当一个函数需要改变传递给它的指针的值时。
考虑如下函数,它将一个指针移动到指向字符串中的下一个字符:
void scanTo(const char **p, char c)
{
while( **p && **p != c)
++*p;
}
传递给scanTo的第一个参数是一个指向指针的指针,该指针值是我们希望改变的。这意味着必须传递指针的地址。
在C++中做法是使用指向指针的引用作为函数参数,而不是使用指向指针的指针作为参数:
void scanTo(const char *&p, char c)
{
while( *p && *p != c)
++p;
}
//.....
char s[ ] = "Hello, World!";
const char *cp = s;
scanTo(cp, ' , ');
4、一个常见的误解是:适用于指针的转换同样适用于指向指针的指针。并非如此!
例如我们知道,一个指向派生类的指针可被转换为一个指向其公共基类的指针:
Circle * c = new Circle;
Shape * s = c; //挺好的
因为Circle是一个Shape,因而一个指向Circle的指针也是一个Shape指针。然而,一个指向Circle指针的指针并不是一个指向Shape指针的指针:
Circle **cc = &c;
Shape **ss = cc; //错误
5、将一个指向非常量的指针转换为一个指向常量的指针是合法的。
但不可以将一个指向“指向非常量的指针”的指针转换为一个指向“指向常量的指针”的指针。