【博文连载】C++中的“引用”

引用就是别名,如下,rnum是num的别人,对rnum的操作实际就是对num的操作。这里的&是引用运算符,不是取址运算符。

int num = 1;int &rnum=num;

还可以定义一个对象的别名,如下,注意不能定义一个类的别名,因为它没有具体的内存地址。

Human Mike;Human &rMike=Mike;

还要注意一点是,定义引用时一定要同时对该引用进行初始化。

函数的参数传递有三种方式:

(1)通过值来传递函数参数

当通过值的方式给函数传递参数时,编译器会自动在栈中创建该参数的拷贝,因此,函数处理的是这些副本,一旦函数执行完毕,副本就被释放,原来的参数未被修改。

void swap(int a,int b);     //  声明swap(a,b);                  //  调用

(2)通过指针来传递函数参数

当通过指针的方式给函数传递参数时,实际上传递的是参数的内存地址,而无需在栈中创建参数的拷贝,因此是对参数自身的参数。

void swap(int *a,int *b);   //  声明swap(&a,&b);                //  调用

(3)通过引用来传递函数参数

对比于指针的间接访问,采用引用的方式可以直接访问内存地址。另外,使用别名的方式传递参数比用指针传递更加方便和清晰,并且具有指针的功能。

void swap(int &ra,int &rb); //  声明swap(a,b);                  //  调用

传递对象的方式有四种:

(1)用值来传递对象

假如仅仅是传递变量的话,采用指针或引用这种按址传递方式的优势不是很明显,但假如是传递较大的对象的话,则优势比较明显。这是因为按值方式向函数传递一个对象时,会建立该对象的拷贝,而从函数返回一个对象时也要建立被返回对象的拷贝。测试代码如下:

#include<iostream>using namespace std;class A{public:     A();     A(A&);     ~A();};A::A(){     cout << "执行构造函数创建一个对象\n";}A::A(A&){     cout << "执行复制构造函数创建该对象的副本\n";}A::~A(){     cout << "执行析构函数删除该对象\n";}A func(A one);int main(){     A a;     func(a);     system("pause");     return 0;}A func(A one){     return one;}

输出结果:

执行构造函数创建一个对象执行复制构造函数创建该对象的副本执行复制构造函数创建该对象的副本执行析构函数删除该对象执行析构函数删除该对象执行析构函数删除该对象

(2)用指针来传递对象

测试代码如下:

#include<iostream>using namespace std;class A{public:     A();     A(A&);     ~A();};A::A(){     cout << "执行构造函数创建一个对象\n";}A::A(A&){     cout << "执行复制构造函数创建该对象的副本\n";}A::~A(){     cout << "执行析构函数删除该对象\n";}A *func(A *one);int main(){     A a;     func(&a);     system("pause");     return 0;}A *func(A *one){     return one;}

输出结果:

执行构造函数创建一个对象

(3)用const指针来传递对象

采用指针来传递对象,虽然可以避免调用复制构造函数和析构函数,但由于它得到了该对象的内存地址,可以随时修改对象的数据,因此它破坏了按值传递的保护机制。如果用const指针来传递对象,就可以防止任何试图对该对象所进行的操作行为,并且保证返回一个不被修改的对象。测试代码如下:

#include<iostream>using namespace std;class A{public:     A();     A(A&);     ~A();     int get()const{return x;}     void set(int i){x=i;}private:     int x;};A::A(){     cout << "执行构造函数创建一个对象\n";}A::A(A&){     cout << "执行复制构造函数创建该对象的副本\n";}A::~A(){     cout << "执行析构函数删除该对象\n";}const A *const func(const A *const one);int main(){     A a;     a.set(99);     func(&a);     system("pause");     return 0;}const A *const func(const A *const one){     cout << one->get() << endl;     return one;}

输出结果:

执行构造函数创建一个对象99

(4)用引用来传递对象

由于引用不能重新分配去引用另一个对象,它始终是常量。测试代码如下:

#include<iostream>using namespace std;class A{public:     A();     A(A&);     ~A();     int get()const{return x;}     void set(int i){x=i;}private:     int x;};A::A(){     cout << "执行构造函数创建一个对象\n";}A::A(A&){     cout << "执行复制构造函数创建该对象的副本\n";}A::~A(){     cout << "执行析构函数删除该对象\n";}A &func(A &one);int main(){     A a;     a.set(99);     func(a);     system("pause");     return 0;}A &func(A &one){     cout << one.get() << endl;     return one;}

输出结果:

执行构造函数创建一个对象99

引用不但实现了指针的功能,而且使用起来更加方便,那为什么还要指针?因为指针可以为空,但引用不能为空,指针可以被赋值,引用只可以被初始化,不可以被赋为另一个对象的别名。如果想使一个变量记录不同对象的地址,就必须使用指针。要明白的一点是不可以直接用引用来指向堆中新建的空间,引用只是个别名,不可以作为指针来使用。如int &r=new int;是错误的。

 

 招聘信息 

(0)

相关推荐

  • C++核心编程

    时间:2021-03-09 13:17:24                        主要针对C++面向对象编程技术做详细讲解,探讨C++中的核心和精髓. 1.内存分区模型 C++程序在执行时, ...

  • C++:引用的简单理解

    前言:引用是C++一个很重要的特性,最近看了很多有关引用的资料和博客,故在此对引用的相关知识进行总结 一.什么是引用 引用,顾名思义是某一个变量或对象的别名,对引用的操作与对其所绑定的变量或对象的操作 ...

  • 浅拷贝,深拷贝和写时拷贝(string类)

    浅拷贝浅拷贝:编译器只是直接将指针的值拷贝过来,结果多个对象共用了一块内存,当一个对象调用了析构函数将这块内存释放掉之后,另一些对象不知道这块空间已经还给了系统,再次调用析构函数进行释放时发现已经释放 ...

  • 【博文连载】中值滤波算法的介绍

    言归正传,我们先挑一个相对最简单的滤波算法(其实均值滤波更简单,但是它对边缘的保持太差,那就稍微努力点用中值滤波吧).进行中值滤波不仅可以去除孤点噪声,而且可以保持图像的边缘特性,不会使图像产生显著的 ...

  • 【博文连载】C++中的“命名空间”

    命名空间主要解决命名冲突的问题.命名空间可以存放类.对象.函数.变量.结构体等.假如要使用命名空间中的变量或者对象,那么使用using namespace来指定某个命名空间,释放该命名空间中所有的变量 ...

  • 【博文连载】C++中的“栈与堆”

    一般来说,写程序就是与数据打交道,在执行程序某一功能的时候,将该功能所需要的数据加载到内存中,然后在执行完毕的时候释放掉该内存. 数据在内存中的存放方式有以下几种: (1)栈区--由编译器自动分配并且 ...

  • 【博文连载】C++中的“指针”

    指针是用来保存内存地址的变量.每个被定义的变量都有自己的地址,可以用指针来存放任何被定义的变量的地址.如(p存放的是变量的地址,*p存放的是变量的数据.): int a;  //  定义一个整型变量a ...

  • 【博文连载】DDR3中的ODT动态模式详解

    首先举一个例子: 早期的DDR(注:DDR2开始支持ODT功能),当向内存写入数据时,如果只有一条内存,那么这条内存就自己进行信号的终结,终结电阻等效为150Ω.如果为两条内存,那么他们会交错的进行信 ...

  • 【博文连载】PCIe扫盲——PCI总线中的Reflected-Wave Signaling

    PCI Spec规定了每个PCI总线上最多可以连接多达32个PCI设备,但是实际上却远远达不到32个,33MHz的32位PCI总线一般只能连接10到12个负载. 注:如果使用插槽连接,则一个连接算两个 ...

  • 干货 | 参考文献在论文中正确引用的方法

    一.当文内引用采用姓名和年份的方式,则以时间顺序在文内列出多个文献,再以字母顺序在文后列出这些文献. 当文内引用采用文献号,则以数字顺序在文内和文后列出文献. 二.不同的期刊因其风格差异可能有不同的引 ...

  • C/C++编程笔记:C++中的引用!(含引用和指针的对比)

    当将变量声明为引用时,它将成为现有变量的替代名称.通过在声明中添加"&",可以将变量声明为引用. C++: 输出: x = 20 ref= 30 应用范围:  修改函数中传 ...

  • 如何删除Excel合并计算中的引用位置?

    我们在使用excel表格中的合并计算命令的时候,上一次的引用位置会保留下来,如 何将其删除呢? 1.我们点击数据选项卡,找到合并计算按钮. 2.会弹出合并计算的对话框,能够看到之前引用位置的数据. 3 ...