首页 > 代码库 > c++中引用的一些研究

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的值,但是如果我们输出类中的值,那个值是不变的。也就是说引用时可以当作普通变量操作的,也可以像普通变量那样直接把自己的值拷贝给其他相同变量。