c++中引用的一些研究

前言

在c++中,一个变量的引用代表这个变量的别名。如果我们为一个变量定义了引用,则对该引用的操作等效于对所引用的变量的操作。那么,如果在一个函数中返回引用类型,将会产生什么样的现象?

引用作为返回值

下边写一个简单的程序演示引用作为返回值的情况。

class ts
{

public:
        ts()
        {
                num=10;
                strcpy(text,"hahaha");
        }
        int num;
        char text[10];
};

class test
{
        ts test_ts;
public:
        test()
        {
        }
        ts& getTs()
        {
                return test_ts;
        }
        void printTs()
        {
                std::cout<<"ts num:"<<test_ts.num<<"ts text"<<test_ts.text<<std::endl;
        }
};
int main()
{
        test test1;
        ts& ts1=test1.getTs();     
        
        printf("%d\n",ts1.num);   
        
        printf("%s\n",ts1.text);  
        ts1.num=20;
        printf("ts1:%d\n",ts1.num);
        test1.printTs();
        return 1;
}
         

上边的程序简单的定义了可以返回引用类型的成员函数getTs()。在主函数中我们再定义一个引用并将其初始化为getTs()返回的引用值,之后我们对得到的引用返回值ts1赋值。实际运行后会发现,此时对ts1引用赋值其实就等同于对函数返回的引用所指向的成员变量赋值。简单总结一下,引用类型跟别的类型一样,你可以定义引用类型指向已经存在的引用,此时操作新定义的引用等效于操作已经存在的引用。如果一个函数返回了一个引用,则你对返回的引用修改就等效于对函数中这个引用所指向的变量的修改。注意引用在定义的时候需要直接初始化,因此我们必须用上边例子中的形式直接定义引用并利用函数返回值初始化。

引用和const

我们还可以在引用前加上const,例如const int &x。此时要注意的是,const并非是修饰这个引用本身(也就是引用所指的方向,这个本来就不能修改,不需要专门指定个const)不能修改,而是指引用所引用的变量为const类型。也即是说此时引用所引用的变量是只读的。重新回到前边的例子:

class ts
{

public:
        ts()
        {
                num=10;
                strcpy(text,"hahaha");
        }
        int num;
        char text[10];
};

class test
{
        ts test_ts;
public:
        test()
        {
        }
        const ts& getTs()
        {
                return test_ts;
        }
        void printTs()
        {
                std::cout<<"ts num:"<<test_ts.num<<"ts text"<<test_ts.text<<std::endl;
        }
};
int main()
{
        test test1;
        const ts& ts1=test1.getTs();     
        
        printf("%d\n",ts1.num);   
        
        printf("%s\n",ts1.text);  
        ts1.num=20;//error
        printf("ts1:%d\n",ts1.num);
        test1.printTs();
        return 1;
}

在上边的例子中,我们让一个函数返回了一个const引用,并用一个const引用接受这个引用返回值。此时我们对这个引用修改,这程序会编译不过,因为我们尝试修改一个只读类型。注意,由于函数返回的是const引用,所以我们用来接受函数返回值的引用变量也要定义为const,否则也会编译不过。上边这个例子在实际编程中是非常常用的,我们可以用这种方法返回某个对象或者结构体的const引用,这样既可以省去函数返回时变量拷贝的开销,又可以安全的在函数外部读取某些变量。

前边的例子中我们都是通过一个引用类型来接受函数返回的引用,其实我们也可以直接用一个跟返回引用引用对象相同类型的变量来接受函数返回的引用。例如:

int main()
{
        test test1;
        ts ts1=test1.getTs();     
        
        printf("%d\n",ts1.num);   
        
        printf("%s\n",ts1.text);  
        ts1.num=20;
        printf("ts1:%d\n",ts1.num);
        test1.printTs();
        return 1;
}

经过刚才的修改,程序可以编译通过,也就是说我们可以修改ts1的值。但是需要注意的是,此时我们只是修改了函数返回引用所指向对象的一个副本的值,而非对象本身的值。上边的程序的输出可以看出,尽管我们修改了ts1的值,但是如果我们输出类中的值,那个值是不变的。也就是说引用时可以当作普通变量操作的,也可以像普通变量那样直接把自己的值拷贝给其他相同变量。

c++中引用的一些研究,布布扣,bubuko.com

时间: 2024-08-07 20:48:30

c++中引用的一些研究的相关文章

C++中引用的底层实现

为了研究一下C++中引用的底层实现,写了一个小代码验证其中的基本原理. 引用是一个变量的别名,到底会不会为引用申请内存空间?如果申请空间,空间存放的是什么,下面的代码就主要解决这个疑问. 代码如下,详细见代码注释 1 #include <iostream> 2 #include<string> 3 #include <vector> 4 #include <algorithm> 5 using namespace std; 6 7 class Test 8

【JAVA】在jar文件中引用图片等外部资源的问题

很多时候我们需要把java程序导出成可执行的jar包,但是往往会遇到一个问题:程序中引用的外部资源如图片等在可执行jar包中失效.笔者自己也遇到了这个问题,查阅了网上的一些资料,写得不太易懂,稍微研究了一下算是解决了这个问题,在这里记录下来. 我们以一个特别简单的程序为例,在JFrame中放置一张图片,工程的文档结构如下: 注意到图片资源是存放在src下的.代码如下: 1 package in.love1017best; 2 3 import javax.swing.*; 4 5 public

.net 工程中引用出现感叹号

在工程中引用出现感叹号,有两个原因 原因1:  这是由于之前引用的Dll文件不见了. 右键有感叹号的项,然后选择 "属性" 里边有一个路径属性 这个路径就是之前这个Dll文件的路径,现在这个文件不在了,你需要找到现在这个文件的路径 右键有感叹号的项,然后选择"移除" 右键"引用",选择添加引用,然后选择那个不在的dll的真实路径 其他的项用相同的方式处理 原因2:可能是引用的.Net版本高于了当前工程的.Net版本 更改所引用的工程文件的.Net

php 中引用的应用

<?php // http://blog.csdn.net/samxx8/article/details/37564103 /** 在PHP 中引用的意思是:不同的名字访问同一个变量内容. (1) 变量之间的引用: $a = 10 ; $b =$a ; // 此时$b和$a所指向的是同一存储地址 ,如果$a = 11 ; 则zend会开辟一个新的单元从来是的$a = 11 ; $b 还是原来的地址 $a = 10 ; $b =&$a ; // 此时$b 就是$a的别名,比如这个人叫小张,大名

Windows Store App 全球化:在后台代码中引用字符串资源

上文提到了引用字符串资源具有两种方式,分别是在XAML元素中和在后台代码中引用资源文件中的字符串资源.在第一小节已经介绍了如何在XAML元素中引用字符串资源,本小节将讲解在后台代码中引用字符串资源的相关知识点. 下面通过一个示例直接讲述如何在后台代码中引用资源文件中的字符串资源.新建一个Windows应用商店的空白应用程序项目,并命名为StringResourcesInCode.在项目中新建一个名为"Strings"的文件夹,在"Strings"文件夹下新建名为&q

linux系统中各个路由表的研究

linux中有0~255共256张路由表.其中0号表示unspec(未指定),253,254,255分别表示default.main.local表.除了以上4张表外的其他表都是留给用户指定的表.现在就说下以上5张系统表的作用. 首先是0号表unspec.这张表可以理解成所有路由表的总和,也就是说所有路由表中的路由条目在这个表中都会有一条相对应.这样如果想看看系统中所有路由表的路由条目就可以看这张表.当然对这张表中的路由条目操作也等同于对其他表中对应的路由条目操作,因此可要小心千万别清空这个路由表

C++中引用(&)的用法和应用实例

C++中引用(&)的用法和应用实例 对于习惯使用C进行开发的朋友们,在看到c++中出现的&符号,可能会犯迷糊,因为在C语言中这个符号表示了取地址符,但是在C++中它却有着不同的用途,掌握C++的&符号,是提高代码执行效率和增强代码质量的一个很好的办法.在 c++学习提高篇(3)---隐式指针的文章中我详细介绍了在隐式指针&的用法,其实这两个概念是统一的. 引用是C++引入的新语言特性,是C++常用的一个重要内容之一,正确.灵活地使用引用,可以使程序简洁.高效.我在工作中发现

php中引用和赋值的区别主要在哪里

php中引用和赋值的区别 <pphp 的引用允许用两个变量来指向同一个内容. 相当于他们可以是 不同的名字,却可以指向 同一个 物理空间. 赋值,它实际上意味着把右边表达式的值赋给左边的运算数. 相当于,他们是 不同的名字,不同的物理空间 示例: 引用 $b = '3'; echo $b; //3 $a = &$b; echo $a; //3 $b = 4; echo $b ; //4 echo $a; //4 $a = 5; echo $b ; //5 echo $a; //5 当$a 引

如何定义一个命令的别名,如何在命令中引用另一个命令的执行结果? &nbsp;

1.命令别名:alias alias:显示当前shell进程所有可用的命令别名 alias NAME="VALUE":命名别名 注意:在命令行中定义的别名,仅对当前shell进程有效,如果想永久有效,要定义配置文件 仅对当前用户:~/.bashrc 对所有有效:/etc/bashrc 2. 使用管道命令 | COMMAND1 | COMMAND2 | COMMAND3 |... 最后一个命令会在当前shell进程的子shell进程中执行: 如何定义一个命令的别名,如何在命令中引用另一个