常见问题

2019-12-26  本文已影响0人  wjundong

c++中,引用和指针的区别是什么?

C++ primer 中对 对象的定义:对象是指一块能存储数据并具有某种类型的内存空间,一个对象 a,它有值和地址 &a,运行程序时,计算机会为该对象分配存储空间,来存储该对象的值,我们通过该对象的地址,来访问存储空间中的值。

指针 p 也是对象,它同样有地址 &p 和存储的值 p,只不过,p 存储的数据类型是数据的地址。如果我们要以 p 中存储的数据为地址,来访问对象的值,则要在 p 前加解引用操作符 '*', 即 *p。

对象有常量(const)和变量之分,既然指针本身是对象,那么指针所存储的地址也有常量和变量之分,指针常量是指,指针这个对象所存储的地址是不可以改变的,而指向常量的指针的意思是,不能通过该指针来改变这个指针所指向的对象。

我们可以把引用理解成变量的别名。定义一个引用的时候,程序把该引用和它的初始值绑定在一起,而不是拷贝它。计算机必须在声明 r 的同时就要对它初始化,并且,r 一经声明,就不可以再和其它对象绑定在一起了。

实际上,你也可以把引用看做是通过一个常量指针来实现的,它只能绑定到初始化它的对象上。

关于指针和引用的对比,可以参看<<more effective C++>>中的第一条条款,引用的一个优点是它一定不为空,因此相对于指针,它不用检查它所指对象是否为空,这增加了效率

但引用不足之处在于给函数传递参数时无法直观判断值是否被修改

比如下面的代码:

int a,b,*p,&r=a;//正确
r=3;            //正确:等价于a=3
int &rr;        //出错:引用必须初始化
p=&a;           //正确:p中存储a的地址,即p指向a
*p=4;           //正确:p中存的是a的地址,对a所对应的存储空间存入值4
p=&b;           //正确:p可以多次赋值,p存储b的地址

哪些函数不能是虚函数?

构造函数,构造函数初始化对象,派生类必须知道基类函数干了什么,才能进行构造;当有虚函数时,每一个类有一个虚表,每一个对象有一个虚表指针,虚表指针在构造函数中初始化;
内联函数,内联函数表示在编译阶段进行函数体的替换操作,而虚函数意味着在运行期间进行类型确定,所以内联函数不能是虚函数;
静态函数,静态函数不属于对象属于类,静态成员函数没有this指针,因此静态函数设置为虚函数没有任何意义。
友元函数,友元函数不属于类的成员函数,不能被继承。对于没有继承特性的函数没有虚函数的说法。
普通函数,普通函数不属于类的成员函数,不具有继承特性,因此普通函数没有虚函数。

出现 segment fault 的原因

  1. 访问非法内存

  2. 数据越界
    数据越界越界的地方不一定是非法内存。但是越界过多,把栈也越过去,就有问题

  3. 修改只读内存
    比如修改了只读常量的内存

  4. 堆栈溢出
    比如无尽递归,或者在函数里面声明大数组,每次调用耗费栈的大量空间

使用二级指针

  1. 需要改变指针本身的时候
    比如链表释放,传入二级指针以便链表释放后将头指向空

  2. 传入指针数组
    传入一个数组,数组元素是指针 *p[]

上一篇下一篇

猜你喜欢

热点阅读