/*按地址传递*/
#include <iostream>
using namespace std;
void swap(int *a, int *b)
{
int c;
c = *a;
*a = *b;
*b = c;
}
int main()
{
int a = , b = ;
cout << "交换前" << "a: " << a << " b: " << b << endl;
swap(&a, &b); // 按地址传递
cout << "交换后" << "a: " << a << " b: " << b << endl;
return ;
}

按别名传递

/*按别名传递*/
/*我们可以将a和b的别名传递到swap函数中,将swap函数的接收参数改为接收两个别名,调用时候将a和b传递进去即可,
这样参数a和b就变成了主函数中的a和b的别名,由于别名即自身,所以对别名的操作即是对main函数的a和b的操作,
或者说参数a和b即main函数中的a和b*/
#include <iostream>
using namespace std;
void swap(int &a, int &b)
{
int c;
c = a;
a = b;
b = c;
}
int main()
{
int a = , b = ;
cout << "交换前" << "a: " << a << " b: " << b << endl;
swap(a, b);
cout << "交换后" << "a: " << a << " b: " << b << endl;
return ;
}

按值传递比较消耗系统资源,下面来演示

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

上面代码如果改成按地址传递就会少调用一次复制构造函数,当然跟着也会少调用一次析构函数,当然如果仍然返回一个值的话,

仍然会调用一次复制构造函数来创建一个返回值,仍然浪费了系统资源,

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

当然如果仅仅返回一个地址的话,就会省去上面的因要返回一个值而调用复制构造函数和析构函数的过程

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

按值传递虽然可以避免重复调用复制构造函数和析构函数 ,但是由于它得到了该对象的内存地址,可以随时修改该对象的数据。所以它实际上是破坏了按值传递的保护机制,不过我们仍然有解决办法,那就是用const指针来接收对象,这样就可以防止任何试图对该对象进行操作的行为,并且保证返回一个不可被修改的对象

这样的话我们无法通过返回的地址来修改对象的值,但是我们仍然可以通过该对象的名字来修改该对象。因为指向常量的长指针只是限制我们用该指针修改它指向的对象的值,但是它并不会改变原始对象的属性,不修改该对象的值的操作可以利用传递回来的地址进行,

注意:子函数返回的指向常量的长指针的值 必须用指向常量的长指针来接收;否则会报错!!!!!!!!!!!!!!!!!!!!!!!!

/*注意不要用对象来接收返回的别名,由于别名并不是对象,只是原来对象的另一个名字,所以呢执行复制构造函数以后,并没有*/
#include <iostream>
using namespace std;
class A
{
public:
A() {cout << "执行构造函数创造一个对象\n";}
A(A&) {cout << "执行复制函数创建该对象的副本\n";}
~A() {cout << "执行析构函数删除该对象\n";}
int get()const{return x;}
void set(int i) {x = i;}
private:
int x;
};
const A *const fun(const A *const one) //保证传进来的数据不被修改,返回的值也不被修改
{
one->get();
return one;
}
int main()
{
A a;
const A *const p = fun(&a);
a.set();
cout << "p:" << p << endl;
cout << "a:" << &a << endl;
return ;
}

下面是引用的代码,注意当子函数返回一个引用的时候不能用一个对象来接收该引用,这个对象是不会得到一个对象的数据的,因为返回的仅仅是一个引用的名字而已,而要定义一个引用来接收返回的引用,如果返回一个对象的时候倒是可以定义一个对象来接收

/*注意不要用对象来接收返回的别名,由于别名并不是对象,只是原来对象的另一个名字,
即返回的不是对象,而是对象的另一个名字,所以不能用对象来接收一个别名,而要用一个别名来接收它
如果返回的是一个对象的话就可以用一个对象来接收它,这样执行复制构造函数的时候也会复制返回的对象的数据
所以执行复制构造函数之后并没有复制该对象的数据*/ /*别名常量不能修改它所引用的对象的数据const A &b = a; 即定义一个类A中a对象的别名常量b,*/
#include <iostream>
using namespace std;
class A
{
public:
A() {cout << "执行构造函数创造一个对象\n";}
A(A&) {cout << "执行复制函数创建该对象的副本\n";}
~A() {cout << "执行析构函数删除该对象\n";}
int get()const{return x;}
void set(int i) {x = i;}
private:
int x;
};
A& fun(A &one)
{
one.get();
return one;
}
int main()
{
A a;
A &b = fun(a);
a.set();
cout <<b.get()<< endl;
return ;
}

引用本来就是常量,我们不能改变它所引用的对象,而且当我们不想让该引用修改它所引用的对象的值的时候,我们可以把它定义为别名常量,

这个时候用该引用修改原对象的名字就是非法的,会报错,只能用原对象的名字来修改这个对象

/*别名常量不能修改它所引用的对象的数据const A &b = a; 即定义一个类A中a对象的别名常量b,这时候不能用b修改a的数据*/
#include <iostream>
using namespace std;
class A
{
public:
A() {cout << "执行构造函数创造一个对象\n";}
A(A&) {cout << "执行复制函数创建该对象的副本\n";}
~A() {cout << "执行析构函数删除该对象\n";}
int get()const{return x;}
void set(int i) {x = i;}
private:
int x;
};
const A& fun(const A &one) //保证返回的值不被修改,传进来的对象也不被修改
{
one.get();
return one;
}
int main()
{
A a;
const A &b = fun(a);
a.set();
cout <<b.get()<< endl;
return ;
}

c++的引用(二)的更多相关文章

  1. Unity Inspector 给组件自动关联引用(二)

    通过声明的变量名称,主动关联引用. 使用这个关联引用两种方式1.  给你组件继承  MonoAutoQuote 点击组件inspector 按钮执行2.  给你组件类添加[AAutoQuote] 特性 ...

  2. JDK1.8新特性之(二)--方法引用

    在上一篇文章中我们介绍了JDK1.8的新特性有以下几项. 1.Lambda表达式 2.方法引用 3.函数式接口 4.默认方法 5.Stream 6.Optional类 7.Nashorm javasc ...

  3. C语言教学--二维数组和指针的理解

    对于初学者对二维数组和指针的理解很模糊, 或者感觉很难理解, 其实我们和生活联系起来, 这一切都会变得清晰透彻. 我们用理解一维数组的思想来理解二维数组, 对于一维数组,每个箱子里存放的是具体的苹果, ...

  4. 【学习笔记】【C语言】二维数组

    1. 什么是二维数组 一个数组能表示一个班人的年龄,如果想表示很多班呢? 什么是二维数组?int ages[3][10]; 三个班,每个班10个人 相当于3行10列 相当于装着3个一维数组 二维数组是 ...

  5. jenkins-APP打包页面展示二维码

    背景: 客户要求在APP打包页面展示二维码.虽然感觉这个功能很鸡肋,但是还是加上吧. 效果展示: 配置: 在上图中,106对应的内容是BuildName,我们可以通过build-name-setter ...

  6. 【Java学习笔记之八】java二维数组及其多维数组的内存应用拓展延伸

    多维数组声明 数据类型[][] 数组名称; 数据类型[] 数组名称[]; 数据类型数组名称[][]; 以上三种语法在声明二维数组时的功能是等价的.同理,声明三维数组时需要三对中括号,中括号的位置可以在 ...

  7. java_方法引用

    什么是方法引用? 个人简述方法引用: 方法引用主要是针对已经有的方法来让目前的编程更加简洁 当我们想要使用一个接口的子类的时候,子类需要重写这个接口中的抽象方法, 被重写的这个方法参数列表固定,返回值 ...

  8. Block 循环引用(上)

    iOS的内存管理机制 Objective-C在iOS中不支持GC(垃圾回收)机制,而是采用的引用计数的方式管理内存. 引用计数:在引用计数中,每一个对象负责维护对象所有引用的计数值.当一个新的引用指向 ...

  9. VS2015+OpenGL4.0开发编译时弹出错误:glaux.lib(tk.obj) : error LNK2019: 无法解析的外部符号 _sscanf,该符号在函数 _GetRegistrySysColors@8 中被引用

    一.问题描述: VS2015+OpenGL4.0开发编译时弹出如下所示的错误: 1>glaux.lib(tk.obj) : error LNK2019: 无法解析的外部符号 _sscanf,该符 ...

  10. 《C语言程序设计》指针篇<二>

    通过指针引用多维数组 如何理解二维数组元素的地址? 要知道,这本书用了整整两页的内容来讲解这方面的知识,从这里足以看出来理解通过指针来引用二维数组是一件比较麻烦的事情,但是我认为理解并不难. 什么是二 ...

随机推荐

  1. BZOJAC400题留念

    BZOJAC400题了...

  2. select标签操作大全

    http://blog.csdn.net/hhhh2012/article/details/8610336

  3. Android 开发笔记“程序安装包APK的制作”

    资源来源:http://blog.csdn.net/qualcent/article/details/6959547 完成Android项目后,需要将程序打包成APK文件(Android Packag ...

  4. SQL中 and or优先级问题

    资源来源:http://www.linuxidc.com/Linux/2012-03/56267.htm 刚刚在项目中遇到这样一个问题,SQL语句如下: select * from LOAN_BACK ...

  5. 帝国cms分页样式修改文件-注意事项

    帝国cms分页样式主要有:内容页分页样式.列表页分页样式以及默认搜索模板使用的搜索样式等几种. 要改这些样式其实也很简单,在网站目录中找到相应的.css文件修改empages属性就行了,但是这样比较麻 ...

  6. python自学笔记(五)python文本操作

    一.python自带方法 r:read 读 w:write 写 a:append 尾行追加 先命令行进入python后 >>>d = open('a.txt','w') #在对应路径 ...

  7. linux 命令大全

    工作了一段时间,开始整理资料,好记性不如烂笔头啊. linux命令大全下载路径: 1.http://www.pc6.com/SoftView/SoftView_28912.html 2.http:// ...

  8. SubLime BracketHighlighter 配置

    很多插件在github上都有比较详细的说明  告知安装位置什么的一般来说 插件都是放在Packages目录里面的   从Github上下载 解压得到的文件夹然后放入到Packages中这个目录在哪里呢 ...

  9. Splunk

    http://www.huxiu.com/article/33724/1.html http://www.netis.com.cn/splunk/%E4%BB%80%E4%B9%88%E6%98%AF ...

  10. hdoj 1874 畅通工程续(单源最短路+dijkstra)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1874 思路分析:该问题给定一个无向图.起始点和终点,要求求出从起始点到终点的最短距离: 使用Dijks ...