多级指针的转换:
有如下的定义两个多级指针:
cv(1,n)Type*cv(1,n-1)*cv(1,n-2)....*cv(1,0) T1;
cv(2,n)Type*cv(2,n-1)*cv(2,n-2)....*cv(2,0) T2;
其中cv表示 const, volatile, const volatile, 或者没有限定.
cv(1,n)表示T1的第n级限定,其他依次类推。
如果T1可以转换为T2(即T2=T1可以编译通过),则必须满足如下条件:
1、对每个j>0,如果cv(1,j)是const,那么cv(2,j)也必须为const
2、如果存在某个j,使cv(1,j)和cv(2,j)不同(这种情况一定是cv(2,j)为const,而cv(1,j)没有限定),那么
对于任意的k (0 < k < j),cv(2,j)必须要被const限制。
举例:
例1 /*T1中的最左边没有const,而T2是cv(1,2)有的,即cv(1,2)和 cv(2,2)不同,那么cv(2,1)也必须为const才可以转换 */ int **T1 = NULL; const int *const*T2 = NULL; T2 = T1;//ok //下面这种情况就不能转换 int **T1 = NULL; const int **T2 = NULL; T2 = T1;//error 例2 const int **const***T1 = NULL; const int **const*const*const*T2 = NULL; T2 = T1;//ok const int **const***T1 = NULL; const int **const*const**T2 = NULL; T2 = T1;//error 总结:如果指针T1能够转换为T2类型,即T1可以赋值给T2,则必须满足如下两个条件: 1、在T1被const限定的地方,T2也必须被const限定;如果某个位置T2被限定了而 2、T1没有被限定,那么从该位置起,后面的每级指针(即0<k<j的位置)都必须被限定。
条件1保证了T1指向的const的变量不会被T2所修改,条件2保证了T2指向的const变量不会被T1修改
有如下例子,说明在不满足规则2的情况下,则会出现const变量被修改的情况int main() { const char c = ’c’; char* pc; const char** pcc = &pc; //1: not allowed *pcc = &c; *pc = ’C’;//2: modifies a const object return 0; }
参考文献c++INTERNATIONAL STANDARD(2003) A conversion can add cv-qualifiers at levels other than the first in multi-level pointers, subject to the following rules: Two pointer types T1 and T2 are similar if there exists a type T and integer n > 0 such that: T1 is cv (1 , 0 )pointer to (cv 1 , 1) pointer to . . . cv (1 ,n − 1) pointer to cv (1 ,n )T and T2 is cv (2 , 0 )pointer to (cv 2 , 1) pointer to . . . cv (2 ,n − 1) pointer to cv (2 ,n) T where each cv (i, j) is const, volatile, const volatile, or nothing. The n-tuple of cv-qualifiers after the first in a pointer type, e.g., cv (1 , 1) , cv (1 , 2) , . . . , cv (1 ,n) in the pointer type T1, is called the cv- qualification signature of the pointer type. An expression of type T1 can be converted to type T2 if and only if the following conditions are satisfied:
- the pointer types are similar.
- for every j > 0, if const is in cv (1 , j )then const is in cv( 2 , j ), and similarly for volatile.
-if the cv (1 , j) and cv (2 , j )are different, then const is in every cv (2 ,k) for 0 < k < j.
[Note: if a program could assign a pointer of type T** to a pointer of type const T** (that is, if line //1 below was allowed), a program could inadvertently modify a const object (as it is done on line //2). For example,