首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

在C++中,如果"int a= 3;int* p= &a;",那么为什么不允许"const int* &pp = p“,而允许"const int* const &pp = p”呢?

在C++中,如果"int a= 3;int* p= &a;",那么为什么不允许"const int* &pp = p",而允许"const int* const &pp = p"呢?

首先,我们需要了解C++中指针和引用的概念。

指针是一个变量,它存储了一个内存地址,可以通过解引用操作符(*)来访问该地址上存储的值。指针可以被修改,可以指向不同的内存地址。

引用是一个已存在对象的别名,它在创建时必须初始化,并且不能被修改为引用其他对象。引用本身并不占用额外的内存空间,它只是给已存在的对象起了一个别名。

现在我们来解释为什么不允许"const int* &pp = p"。

在这个语句中,"const int* &pp"表示一个对指针的引用,即pp是一个引用,它引用了一个指向const int类型的指针。而"p"是一个指向int类型的指针。

如果允许"const int* &pp = p",那么pp就可以引用一个指向int类型的指针p。这样的话,通过pp可以修改p指向的内存地址上存储的值,违背了const int*的常量性质。

而"const int* const &pp = p"则是允许的。

在这个语句中,"const int* const &pp"表示一个对指针的常量引用,即pp是一个引用,它引用了一个指向const int类型的常量指针。"p"是一个指向int类型的指针。

由于pp是一个常量引用,它不能修改为引用其他对象,因此pp不能修改为引用其他指针。而"const int* const"表示指针本身是一个常量,即不能通过pp修改p指向的内存地址上存储的值。

综上所述,"const int* &pp = p"不被允许,因为它违背了const int的常量性质,而"const int const &pp = p"是允许的,因为它保持了指针的常量性质。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

《挑战30天C++入门极限》C++面向对象编程入门:类(class)

但是大家注意到没有,标准c不允许结构体声明函数的,但c++的类可以,这一点就和c有了本质的区别,很好的体现了c++面向对象的特点!   ...a的分量(或者叫数据成员,或者叫属性)score;   c语言中结构体的各成员他们的默认存储控制是public c++类的默认存储控制是private,所以的成员如果需要外部掉用一定要加上关键字...答案是这样的:类的定义,一般成员函数的规模一般都比较小,而且一些特殊的语句是不能够使用的,而且一般会被自动的设置成为inline(内联)函数,即使你没有明确的声明为inline,那么为什么有会被自动设置成为...在上面的代码我们看到了,外部全局和类内部都有一个叫做pp的整形变量,那么我们要区分操作他们用什么方法?   ...类体的有一个地方要注意 const static int gbs = 5;//好球单位得分 const static int bbs = -3;//坏球单位扣分   之所以要修饰成const

67210

C++ 指针总结

写这篇文章回顾下C++大学学习时候的误区,希望可以让和我一样的同学少走点弯路。 指针 这是我大学的噩梦,好几个问题一直脑子里转来转去,虽然老师讲了指针就是一块内存,它可以指向另一个内存。...头大的问题: 1、*p , **p , ***p 怎么可以无限的☞下去? 2、 &和指针又是什么关系 3int * array = a[n] 数组和指针啥关系?...为什么要用指针? ---- 解决上面的问题之前,先弄清,指针是什么,我们为什么要用它。 定义:指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。 那么为什么要用指针?...1、如果我们想在程序中共享一块内存,通俗的说就是好几个地方都想用一个内存的值,是不是这时候用指针比较方便。...然后看下 *p , **p, , ***p的例子: void pointerToPointer(){ int a = 3; int* p = &a; int** pp = &p;

69240

记一次阿里实习生电面经历

int永远在星号左边的。记成“反转”就行了。可以忽略int那么就只有两种形式: const * a和 const a。...可选方案如下: 如果C++的话,使用reinterpret_cast long pp = reinterpret_cast(p); // p 是char *类型 如果ppint型(reinterpret...所以我尝试了reinterpret_cast 如果C++的话,就: int pp = reinterpret_cast(p); // p是char *类型 C语言虽然没这个功能,但其实要想比较指针地址是否是...这也是为什么我们通常把malloc返回值转换为char *不是int *的原因。 8. 回调函数 问:“C++如何实现回调函数” 回调函数,挺熟的名字,callback。。。...记得安卓里面见到过。就扯了一下安卓。。 问:“那么C++该如何实现” 接下来,确实也是运气。脑袋里冒出个函数指针,就脱口而出了,说了个一般的函数指针用法。貌似说对了。

42610

从零开始学C++之boost库(一):详解 boost 库智能指针

(),reset 函数构造一个临时对象,它的成员px=0, swap 函数调换 pp.px 与 (this_type)(p).px, 即现在pp.px = 0; //解绑 临时对象接管了裸指针...如果你的C++基础比较好,可以想到拷贝构造函数跟构造函数一样,如果有对象成员是需要先构造对象成员的(这一点 也可以从调用堆栈上看出),故可以shared_count 类的拷贝构造函数设置断点,然后就可以跟踪进去...shared_ptr(new int(2)), g()); } 如bad 函数内,假设先构造了堆对象,接着执行g(), g 函数内抛出了异常,那么由于裸指针还没有被智能指针接管,就会出现内存泄漏...从输出可以看出,当p = p2; 时并未增加use_count_,所以p2.use_count() 还是返回1,p 提升为 p3,增加了 use_count_, p3.use_count() 返回...参考 : C++ primer 第四版 Effective C++ 3rd C++编程规范 http://www.cnblogs.com/TianFang/

5.8K20

C语言高级指针理解及应用(上)

指针的大小32位平台是4个字节,64位平台是8个字节 指针和指针类型 来看代码: int num=10; int *p=# 那如果写成这样 int num=10; char *p=#...指针的解引用: 我们都知道 int*p=&num,那么这个*号是什么;怎么理解; 引用《c语言深度剖析》的文章; 4.1.2,“*”与防盗门的钥匙 这里这个“*”号怎么理解?...比如:char*的指针解引用就只能访问一个字节,int*的指针的解引用就能访问四个字 节。...二级指针 指针也是一个变量,那存放指针这个变量的地址在哪,怎么找到,我们这里引入二级指针的概念 a的地址存放在pp的地址存放在pppp就是二级指针。...int b=20; *pp=&b;//等价于p=&b; **pp先通过*pp找到p,然后对p进行解引用操作:*p,那找到的是a. **pp=30;//等价于把30赋给a。

45130

C++继承(多继承、菱形继承?)

,相当于派生类的private成员,也就是说只能通过子类的类内或基类的类内进行修改,其他地方是不允许访问的。...派生类的默认成员函数 6个默认成员函数,“ 默认 ” 的意思就是指我们不写,编译器会变我们自动生成一个,那么派生类,这几个成员函数是如何生成的?...为什么? 因为如果不显式的指明是 Person 的赋值重载,不同的作用域里面,子类的赋值重载和父类的赋值重载形成了隐藏关系,所 以默认调的是子类的赋值重载,所以陷入了死循环。 ​...那么问题来啦,C++编译器是如何通过虚继承解决数据冗余和二义性的? 由于编译器对监视窗口做了优化,我们并不能看到什么猫腻,所以我们打开编译器的内存窗口看一下,并对下面的代码进行观察!...❓ 问题: 有童鞋会有疑问为什么 D B 和 C 部分要去找属于自己的 A?那么大家看看当下面的赋值发生时,d 是不是要去找出 B/C 成员的 A 才能赋值过去?

1.9K20

【C语言】指针&&二级指针&&数组指针&&指针数组详解

4GB 对于64位的机器也同理 这里我们就明白: 32位的机器上,地址是32个0或者1组成二进制序列,那地址就得用4个字节的空间来存储,所以一个指针变量的大小就应该是32个字节 如果在64位机器上,如果有...,但是我们还是应该避免这样写,因为标准并不保证它可行 标准规定: 允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较...pp p是一级指针,pp是二级指针 *pp通过对pp的地址进行解引用,这样找到的是p,*pp访问的其实就是p **pp先通过*pp找到p,然后对p进行解引用操作:*p,这样最终找到了a 1.7 字符指针...(const void* e1, const void* e2) { return *(int*)e1 - *(int*)e2; } void test1() { int arr[] = { 9,8,7,6,5,4,3,2,1,0...3.2 数组传参和指针传参 写代码的时候难免要把【数组】或者【指针】传给函数,那函数的参数该如何设计

10410

从零开始学C++之boost库(一):详解 boost 库智能指针(scoped_ptr 、shared_ptr 、weak_ptr 源码分析)

(),reset 函数构造一个临时对象,它的成员px=0, swap 函数调换 pp.px  与  (this_type)(p).px, 即现在pp.px = 0; //解绑   临时对象接管了裸指针...如果你的C++基础比较好,可以想到拷贝构造函数跟构造函数一样,如果有对象成员是需要先构造对象成员的(这一点 也可以从调用堆栈上看出),故可以shared_count 类的拷贝构造函数设置断点,然后就可以跟踪进去...f(shared_ptr(new int(2)), g()); } 如bad 函数内,假设先构造了堆对象,接着执行g(), g 函数内抛出了异常,那么由于裸指针还没有被智能指针接管,就会出现内存泄漏...从输出可以看出,当p = p2; 时并未增加use_count_,所以p2.use_count() 还是返回1,p 提升为 p3,增加了 use_count_, p3.use_count() 返回...参考 : C++ primer 第四版 Effective C++ 3rd C++编程规范 http://www.cnblogs.com/TianFang/

1.4K00

c++C++的继承&&菱形继承详解

这里的不可见是指基类的私有成员还是被继承到了派生类对象,但是语法上限制派生类对象不管类里面还是类外面都不能去访问它 基类private成员派生类是不能被访问,如果基类成员不想在类外直接被访问,但需要在派生类能访问...(子类成员函数,可以使用 基类::基类成员 显示访问) 需要注意的是如果是成员函数的隐藏,只需要函数名相同就构成隐藏 注意在实际继承体系里面最好不要定义同名的成员 Student的_num和Person....派生类的默认成员函数 6个默认成员函数,“默认”的意思就是指我们不写,编译器会变我们自动生成一个,那么派生类,这几个成员函数是如何生成的?...: int _stuNum; // 学号 }; void Display(const Person& p, const Student& s) { cout << p....假设B组合了A,每个B对象中都有一个A对象 优先使用对象组合,不是类继承 继承允许你根据基类的实现来定义派生类的实现。这种通过生成派生类的复用通常被称为白箱复用(white-box reuse)。

6710

从零开始学C++之boost库(一):详解 boost 库智能指针(scoped_ptr 、shared_ptr 、weak_ptr 源码分析)

使用boost库之前应该先下载后放在某个路径,并在VS 包含目录添加。...(),reset 函数构造一个临时对象,它的成员px=0, swap 函数调换 pp.px 与 (this_type)(p).px, 即现在pp.px = 0; //解绑 临时对象接管了裸指针...如果你的C++基础比较好,可以想到拷贝构造函数跟构造函数一样,如果有对象成员是需要先构造对象成员的(这一点 也可以从调用堆栈上看出),故可以shared_count 类的拷贝构造函数设置断点,然后就可以跟踪进去...f(shared_ptr( new int( 2)), g()); } 如bad 函数内,假设先构造了堆对象,接着执行g(), g 函数内抛出了异常,那么由于裸指针还没有被智能指针接管...= p2; 时并未增加use_count_,所以p2.use_count() 还是返回1,p 提升为 p3,增加了 use_count_, p3.use_count() 返回2;出了大括号,p2 被析构

1.2K30

C++】继承——切片、隐藏、默认成员函数、菱形

private类内可以访问类外部可以访问,不可见类内类外都不可 2.父类private成员子类是不能被访问,如果父类成员不想在类外直接被访问,但需要在子类能访问,就定义为protected。...(子类成员函数,可以使用基类::基类成员显示访问) 需要注意的是如果是成员函数的隐藏,只需要函数名相同就构成隐藏。 注意在实际继承体系里面最好不要定义同名的成员。...那么派生类,这几个成员函数是如何生成的?...如果父类没有默认构造函数,此时我们就需要去子类提供构造函数,但是父类成员不能在子类通过初始化列表进行初始化: 注意:初始化列表必须得去调用父类的构造函数,这是规定死的。...这里可以分析出D对象中将A放到的了对象组成的最下面,这个A同时属于B和C,那么B和C如何去找到公共的A

24430

C++类型转换

int main() { char buf[20] = "abcd"; const char *p = buf; //编译报错,const修饰的内容无法修改 //p[0]...= '1'; char *pp = const_cast(p); pp[0] = '1'; cout << pp << endl; const char...原来的"abcd"不可修改 //*strp = '1'; //不能直接对非指针和非引用的变量使用const_cast操作符去直接移除它的const、volatile和__unaligned...//int j = const_cast(i); return 0; } reinterpret_cast 允许将任何指针类型转换为其它的指针类型;听起来很强大,但是也很不靠谱。...它可以将一个指针转换成一个整数,也可以将一个整数转换成一个指针,实际开发,先把一个指针转换成一个整数,把该整数转换成原类型的指针,还可以得到原来的指针值;特别是开辟了系统全局的内存空间,需要在多个应用程序之间使用时

70420

C++航海王:追寻罗杰的编程之路】继承你学会了么?

基类private成员派生类是不能被访问的,如果基类成员不想在类外直接被访问,但需要在派生类能访问,就定义为protected。可以看出保护成员限定符是因继承才出现的。...; } 3 -> 继承的作用域 继承体系基类和派生类都有独立的作用域。...(子类成员函数,可以使用基类 :: 基类成员显示访问)。 需要注意的是,如果是成员函数的隐藏,只需要函数名相同就构成隐藏。 注意在实际的继承体系里最好不要定义同名的成员。...4 -> 派生类的默认成员函数 6个默认成员函数,“默认”的意思是指我们不写,编译器会为我们自动生成一个,那么派生类,这几个成员函数是如何生成的?...优先使用对象组合,不是类继承。 继承允许你根据基类的实现来定义派生类的实现。这种通过生成派生类的复用通常被称为白箱复用(white-box reuse)。

10310

C语言指针重难点详解

变量为了表示数据,指针可以更好的传递数据,举个例子: 第一节课是 1 班语文, 2 班数学,第二节课颠倒过来, 1 班要上数学, 2 班要上语文,那么第一节课下课后需要怎样作调整?...综上,指针的实质就是数据在内存的地址,指针变量是用来保存这些地址的变量。 3 指针变量 和 指向关系 用来保存 指针 的变量,就是指针变量。...如果指针变量p保存了变量 num的地址,则就说:p指向了变量num,也可以说p指向了num所在的内存块,指针变量pp指向了p所在的内存块,以下面为例: #include  int main...C语言中,我们让指针变量赋值为NULL表示一个空指针,C语言中,NULL实质是 ((void*)0) ,  C++,NULL实质是0。...pb = &b;   pb = p;   printf("*pb = %d\n", *pb);     // 3   const c = 10;   int * const pc = &c;   *pc

6152219

C 语言指针详解

变量为了表示数据,指针可以更好的传递数据,举个例子: 第一节课是 1 班语文, 2 班数学,第二节课颠倒过来, 1 班要上数学, 2 班要上语文,那么第一节课下课后需要怎样作调整?...如果指针变量p保存了变量 num的地址,则就说:p指向了变量num,也可以说p指向了num所在的内存块,指针变量pp指向了p所在的内存块,以下面为例: #include int...C语言中,我们让指针变量赋值为NULL表示一个空指针,C语言中,NULL实质是 ((void*)0) ,  C++,NULL实质是0。...void change(int a) { a++; //函数改变的只是这个函数的局部变量a,随着函数执行结束,a被销毁。age还是原来的age,纹丝不动。...&b; pb = p; printf("*pb = %d\n", *pb); // 3 const c = 10; int * const pc = &c; *pc = 1000

2.5K11

C++:继承与派生

为什么会有继承这样的语法??...(子类成员函数,可以使用 基类::基类成员 显示访问) 3. 需要注意的是如果是成员函数的隐藏,只需要函数名相同就构成隐藏。 4. 注意在实际继承体系里面最好不要定义同名的成员。...(但是有些情况下不可避免,后面会说) 四、派生类的默认成员函数 6个默认成员函数,“默认”的意思就是指我们不写,编译器会变我们自动生成一个,那么派生类,这几个成员函数是如何生成的?...3为什么2用静态成员函数??...多继承可以认为是C++的缺陷之一,很多后来的OO语言都没有多继承,如Java。 3. 继承和组合 优先使用组合,不是类继承 public继承是一种is-a的关系。

10510
领券