1.理解const*
与*const
假设有一个ptr指针,它保存变量vbl的地址。
Type* ptr = &vbl;
当使用指针的时候就涉及到两个对象:指针本身以及本身所指的对象。这就意味着const有三个层级的保护。
1.1. 确保ptr指向唯一的内存
有两种写法
Type* const ptr = &vbl;
Type* const ptr(&vbl);
1.2. 确保不能通过ptr改变vbl的值
const Type* ptr = &vbl;
const Type* ptr(&vbl);
1.3. 希望两者都不会改变
const Type* const ptr = &vbl;
const Type* const ptr(&vbl);
1.4. 怎么记忆呢
从右边向左读
const char* x = &p; /* x 是一个指针,指向 常char的对象*/
char* const x = &p; /* x 是一个常指针,指向char的对象*/
const char* const x = &p; /* x 是一个常指针,指向常char的对象*/
可以把常改成不可变,就好读了。
2.const*
与*
作为函数参数的差别
const*
与*
作为函数参数的情况
1. 不管是const*
还是*
在作为函数传递的时候都是值传递。
#include <iostream>
#include <stdio.h>
struct A {
int a = 0;
float b = 0.0f;
};
void Test_Const(const A* ptr) {
A* tmp = new A();
ptr = tmp;
printf("Test_Const &tmp: %p\n",tmp);
printf("Test_Const ptr: %p\n",ptr);
}
void Test_Ptr(A* ptr) {
A* tmp = new A();
printf("Test_Ptr &tmp: %p\n",tmp);
ptr = tmp;
printf("Test_Ptr ptr: %p\n",ptr);
}
int main() {
A a;
A* ptr = &a;
printf("&a: %p\n",ptr);
Test_Const(ptr);
printf("&a: %p\n",ptr);
A* t_ptr = &a;
Test_Ptr(t_ptr);
printf("&a: %p\n",t_ptr);
return 0;
}
运行结果
这里我做了个实验,这里new的资源释放,不要在意这些细节。我的想法是一个以const*
作为参数一个以*
作为参数。发现在函数里面这个指针都是可以指向其他地方的。
但是函数外面这个指针值是没改变的,所以推断const*
和*
这个指针值传的时候都是值传递的。
2.2. const*
作为函数参数传递的时候
不允许将这个指针复制给其他非常指针
2.3. *
作为函数参数传递的时候
允许将这个指针复制给其他非常指针或常指针
2.4. const*&
与 *&
*&
是允许改变指针的值的
#include <iostream>
#include <stdio.h>
struct A {
int a = 0;
float b = 0.0f;
};
void Test_Ptr(A*& ptr) {
A* tmp = new A();
printf("Test_Ptr &tmp: %p\n",tmp);
ptr = tmp;
printf("Test_Ptr ptr: %p\n",ptr);
}
int main() {
A a;
A* ptr = &a;
printf("&a: %p\n",ptr);
A* t_ptr = &a;
Test_Ptr(t_ptr);
printf("&a: %p\n",t_ptr);
return 0;
}
运行结果
2.5. const*&
应该没这种用法
编译的时候会报这个错
invalid initialization of non-const reference of type
那么对于这里应该怎么改呢
按照我们这意思就应该
void Test_Const(const A*& ptr)
改成
void Test_Const(const A* const & ptr)
于是我们可以进一步的将*&
写成*const&
void Test_Ptr(A* const & ptr)
最后理解下这几种写法
void Test_Ptr(A* ptr); // 传指针,可以改变指针指向内容,可以在函数将其他指针赋值给ptr,但是不会改变函数外ptr的值。
void Test_Ptr(const A* ptr); //不可改变函数指向的值(不能通过该指针),可以在函数内将其他的指针赋值给ptr,不会改变函数外ptr的值
void Test_Ptr(A*& ptr); //以引用的方式传递指针,既可以改变指针本身也可改变指针指向的内容,函数内外都可见
void Test_Ptr(A* cosnt & ptr); //以引用的方式传递指针,可以改变指针指向的内容,但是不能改变指针本身指向的地址。
void Test_Ptr(const A* cosnt & ptr); //以引用的方式传递,不能改变指针值以及指针指向的内容
void Test_Ptr(const A*& ptr);//没有这种用法