博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
指针的引用——在函数中的巧妙应用
阅读量:7229 次
发布时间:2019-06-29

本文共 2385 字,大约阅读时间需要 7 分钟。

hot3.png

前面有一篇文章讲了。并且还提到不能定义指向引用的指针(因为引用不是对象,没有实际的地址)。那么,能否定义指针的引用呢?答案是肯定的,因为指针本身就是一个对象。即然是对象,就能定义一个引用邦定该对象。先来看看指针的引用的用法:

 

int类型为例如下:

void ReferencePointer(){	int		i = 5;		// 变量i	int*	p = &i;		// 指针p,指向变量i	int*&	pr = p;		// 指针的引用,与p指向同一个变量i	cout << i << "  " << *p << "  " << *pr << endl;	i = 10;	cout << i << "  " << *p << "  " << *pr << endl;	cout << "addr: " << p << "  " << pr << endl;	// 指针的引用其它就是指针p的一个别名,和p有相同的地址	pr = NULL;										// 因此也可以给指针赋空	cout << "addr: " << p << "  " << pr << endl;}

结果:

5  5  5

10  10  10

addr: 0045FE50  0045FE50

addr: 00000000  00000000

 

在函数中,指针的引用作为参数可以起到很巧妙的作用。

 

假设有一个书的类Book,基定义如下:

struct Book

{

    string isbn;

    string name;

    double price;

    string author;

};

现在需要这样一个函数:有一个文件存放着一本书的相关信息(ISBN、书名、价格),现要从这个文件中读取信息并赋给Book的对象。

 

要定义这样一个函数,我们首先会想到的是有一个输入(文件的路径)和一个输出(Book的对象)。你可能会这样定义函数:

Book* GetBookFromFile(const string& filePath);

这种方式你必须在函数体内创建Book的对象(也就创建一个Book的内存空间),但函数体内创建的内存空间只在函数的作用域内有效,在函数体外是无效的,也就是说返回的指针将指向一个任意的值,这将是非常危险的。

 

如函数内:

 

在函数被调用后:

 

 

 

 

 

既然不行,您应该会想到另外一种定义方式如下:

Book GetBookFromFile(const string& filePath);

没错,这样定义确实可以,但需要在函数体内声明一个Book的对象,函数返回值的时候会进行一次对象的拷贝。这样增加了一个对象拷贝的过程,使效率降低。

Book GetBookFromFile(const string& filePath){	Book book;	fstream fileInput(filePath);	fileInput >> book.isbn >> book.name >> book.price;	return book;}

 

 

 

 

 

您可能还会想到这种方式:

void GetBookFromFile(Book &book, const string& filePath);

没错,这确实可以解决上面的问题,不用再对对象进行拷贝。但新的问题又来了,上层调用这个函数时,如果要判断返回book对象是否正确获取了文件的信息得逐个地判断基属性是否空,如下代码。这无疑加重了上层调用的负担。

Book book;

GetBookFromFile(book, "E:\\book.txt");

if (!book.isbn.empty() && !book.name.empty() && book.price > 0)

{

    // TO DO ...

}

当然,这有一种改进的方式,就是把返回值类型void改为bool,这样就可以通过返回的bool值确定函数是否成功调用。

 

 

 

针对上面的这个问题,如果返回的是Book的指针,直接判断返回的指针是否为NULL就可以。那么您可以有以下两种定义:

void GetBookFromFile(Book* book, const string& filePath);

void GetBookFromFile(Book*& book, const string& filePath);

当然,我是建议选择第二种方式,因为引用确保了传进来的指针有一个正确的值(引用必须在定义时被初始化)

 

定义如下:

 

void GetBookFromFile(Book* pBook, const string& filePath){	if (pBook == NULL)	{		return;	}	fstream fileInput(filePath);	fileInput >> pBook->isbn >> pBook->name >> pBook->price;}
void GetBookFromFile(Book*& pBook, const string& filePath){	if (pBook == NULL)	{		return;	}	fstream fileInput(filePath);	fileInput >> pBook->isbn >> pBook->name >> pBook->price;}

 

对这两个函数,调用方式都可以如下:

Book* pBook = new Book();	pBook->author = "SimileSunrise";	GetBookFromFile(pBook, "E:\\book.txt");	delete pBook;

 

转载于:https://my.oschina.net/verynix/blog/365828

你可能感兴趣的文章
android复习-AnsyTask
查看>>
JSP页面
查看>>
解决Android SDK Manager更新、下载速度慢
查看>>
LeetCode:Sort List
查看>>
Android ListView复制、删除的实现
查看>>
网络直播电视之M3U8解析篇 (下)
查看>>
Rational Rose2007无法正常启动解决方式
查看>>
“CoreCLR is now Open Source”阅读笔记
查看>>
用Visual C#来清空回收站(2)
查看>>
Yahoo团队总结的关于网站性能优化的经验(转)
查看>>
【转】10分钟搭建NDK的Android开发环境
查看>>
开涛spring3(3.4) - DI 之 3.4 Bean的作用域
查看>>
Flume Channel
查看>>
JS学习(二)
查看>>
Android 获取SDCard中某个目录下图片
查看>>
【Eclipse提高开发速度-插件篇】Eclipse插件安装慢得几个原因
查看>>
Jenkins学习五:更改Jenkins的主目录
查看>>
[JS] 页面回车键提交表单-常用于登录页面
查看>>
奇怪吸引子---Hadley
查看>>
数字三角形问题
查看>>