首页
学习
活动
专区
工具
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

69610

C++ 指针总结

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

70940
  • C++的魔法世界:类和对象的终章

    每个成员变量在初始化列表中只能出现一次,语法理解上初始化列表可以认为是每个成员变量定义初始化的地方 由于某些原因,C++规定必须给每一个成员变量找一个定义的地方,比如被const修饰的变量、引用变量它们在定义的时候必须初始化...int _x; }; int pp::_x = 10; int main() { pp p; cout p....std; class hh;//前置声明 //若不做声明,pp中的友元函数声明不认识hh类 class pp { friend void Fun(const pp& p, const...; int _n; }; void Fun(const pp& p, const hh& h) { cout const A& r = A(); 但它被引用后而匿名对象的空间被销毁,导致野引用,这在语法上是不允许的 反之,没有使用const进行修饰,在编译时会引起编译器的报错 匿名对象作函数缺省值: class

    5000

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

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

    44710

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

    (),reset 函数构造一个临时对象,它的成员px=0, 在swap 函数中调换 pp.px 与 (this_type)(p).px, 即现在pp.px = 0; //解绑 临时对象接管了裸指针...如果你的C++基础比较好,可以想到拷贝构造函数跟构造函数一样,如果有对象成员是需要先构造对象成员的(这一点 也可以从调用堆栈上看出),故可以在shared_count 类的拷贝构造函数设置断点,然后就可以跟踪进去...shared_ptrint>(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/

    6.7K20

    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的地址存放在p中,p的地址存放在pp中,pp就是二级指针。...int b=20; *pp=&b;//等价于p=&b; **pp先通过*pp找到p,然后对p进行解引用操作:*p,那找到的是a. **pp=30;//等价于把30赋给a。

    49030

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

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

    2K20

    【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 数组传参和指针传参 在写代码的时候难免要把【数组】或者【指针】传给函数,那函数的参数该如何设计呢?

    87011

    【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)。

    15610

    从零开始学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_ptrint>(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.7K00

    从零开始学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_ptrint>( new int( 2)), g()); } 如bad 函数内,假设先构造了堆对象,接着执行g(), 在g 函数内抛出了异常,那么由于裸指针还没有被智能指针接管...= p2; 时并未增加use_count_,所以p2.use_count() 还是返回1,而从p 提升为 p3,增加了 use_count_, p3.use_count() 返回2;出了大括号,p2 被析构

    1.4K30

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

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

    43730

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

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

    13910

    C++:继承与派生

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

    18610

    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_castint>(i); return 0; } reinterpret_cast 允许将任何指针类型转换为其它的指针类型;听起来很强大,但是也很不靠谱。...它可以将一个指针转换成一个整数,也可以将一个整数转换成一个指针,在实际开发中,先把一个指针转换成一个整数,在把该整数转换成原类型的指针,还可以得到原来的指针值;特别是开辟了系统全局的内存空间,需要在多个应用程序之间使用时

    72720
    领券