C++——引用 reference

转载请注明出处:http://www.javashuo.com/article/p-qhwzkmqc-gs.html html

pass by value vs. pass by reference (to const)

pass by value是整包传递,无论这个包多大。传的动做其实是压到funtion stack memory中。stack memory中有个好处就是Automatic memory management and garbage collection,可是整包传递的作法实在不高明。C为了解决整包传递效率低下问题引入pointer,不传递整包东西而是改成传递整包东西的地址,32为架构下一个pointer只占4Byte,速度很快。C++引入reference,其行为像pointer,可是处理手段更漂亮更高明。不像指针,你能够把指针的地址打印出来,reference让人看不到摸不着。reference在底部就是一个pointer,pass by reference就至关于pass by pointer那么的快。虽然你可能遇到传单个字符(大小才1Byte),这种状况下pass by value比pass by reference还快,但大多数状况,或者一个通用的准者是首选pass by reference.ios

C中pass by pointer,接收者对pointer的更改会影响发送者。C++中pass by reference 也会存在这个问题。若是你不但愿接收者修改reference,你能够加上const限定。程序员

return by value vs. return by reference (to const)

C++ reference主要用途就是传递 ,能够传递参数,也能够传递返回值。数组

在函数须要return的时候,优先选择return by reference。可是能不能return by reference还要视状况而定。若是你要return的那个东西,事先已经存在过,也就是说已经有一块memory能够存放这个东西,那么OK,你能够return by reference,速度很快。若是事先没有memory接收这个东西,那么你就只能传回一个local object。有些经验老道的程序员还会借助C++中 typename(...)这个特殊语法,返回tmp object加快程序执行效率,这种tmp object的生存周期很短,只有一行代码。不管是local object仍是tmp object,你都不能return by reference。由于一旦出了function,你reference的那块memory就被回收了。严格意义上说被回收的那段memory是function stack memeory。架构

补充:tmp objectide

 

Null reference

C++不容许出现Null reference函数

我的观点:C/C++声明一个变量,声明是不赋值的,属于弱符号。对于一个不赋值的弱符号而言,若是是全局变量则在编译阶段放在.bss节,;若是是局部变量,也就是auto类型,是在程序运行期间自动分布于栈内存。总之是没有开辟内存空间。引用本质上是对一段已经命名的内存空间起个别名。因此对于空引用而言,他就不可能引用一段不存在的内存。C++引用着这种作法和Python很像,Python经过分析一段内存的引用计数来决定是否回收这段内存。固然,C++不会自动帮咱们回收内存,处理好内存是一个程序员的基本素养。this

传递者无需知道接收者以reference形式接收

想一想C在函数中return by pointer的场景spa

returnType *functionName(param list);

__doapl(...)左边参数是一个pointer,返回值是*ths,是pointer指向的一个东西,也就是object,是value。这里体现了reference的好处,接收者此案例中是使用reference接收,固然你使用return by value,也就是包传递也彻底OK,只是效率上没有return by reference快。C++也能够像C同样return by pointer,可是传递着必须作出更改,也就是所传递的形式看起来是pointer。指针

注意体会这种思想,reference做用的场景是涉及到传递的时候,不管是参数传递仍是函数返回值传递。

上图中operator+=返回值是complex& ,其实彻底能够返回void。由于+=执行完其结果已经放到this里面了。这样的确能够,应对c2 += c1彻底没问题。

可是返回void的情形没法应对连续使用+=的状况,例如c3 += c2 += c1,c2 += c1返回值时void,c3 在调用+=的时候就不符合定义了。返回complex&就能够。

reference使用场景

对普通变量的引用

#include<iostream>

int main(int argc, char **argv)
{
    int a = 100;
    int &b = a;
    getchar();
    return 0;
}
View Code

引用b  和 a指向同一块内存

对指针的引用

 1 #include<iostream>
 2 
 3 int main(int argc, char **argv)
 4 {
 5     int a = 100;
 6     int *p = &a;
 7     int* &q = p;
 8     getchar();
 9     return 0;
10 }
View Code

对数组引用

1 #include<iostream>
2 
3 int main(int argc, char **argv)
4 {
5     int ar[10];
6     int(&br)[10] = ar;
7     getchar();
8     return 0;
9 }
View Code

讨论对常量的引用

#include<iostream>

int main(int argc, char **argv)
{
    const int a=10;
    int &b = a;
    getchar();
    return 0;
}
View Code

这个代码在VS 2017下编译不过。a是个常量(使用const限定),b是个引用,可是b没有加const限定,他引用a,会有一种嫌疑,即b能够间接修改a,致使a再也不是常量。因此要想引用常量a,必须使用常引用,代码以下

#include<iostream>

int main(int argc, char **argv)
{
    const int a=10;
    const int &b = a;
    getchar();
    return 0;
}
View Code

像这种引用也是能够的

1 #include<iostream>
2 
3 int main(int argc, char **argv)
4 {
5     int a=10;
6     const int &b = a;
7     getchar();
8     return 0;
9 }
View Code

 跨数据类型的引用

分析以下代码,这里的引用比较怪异。引用 和 被引用指向的内存不同,这是由于引用了临时对象的内存。

1 #include<iostream>
2 
3 int main(int argc, char **argv)
4 {
5     double a=3.14;
6     const int &b = a;
7     getchar();
8     return 0;
9 }
View Code

发现b 和 a并无指向同一块内存。这是由于开辟了临时整形,b引用的是临时整形。这种引用会有潜在风险,万一被引用的临时变量被释放掉(超过做用域),b就引用了一个不存在的东西,程序崩溃。

以下2段代码也是编译不过的

代码1

1 #include<iostream>
2 
3 int main(int argc, char **argv)
4 {
5     const double a=3.14;
6     int &b = a;
7     getchar();
8     return 0;
9 }
View Code

代码2

1 #include<iostream>
2 
3 int main(int argc, char **argv)
4 {
5     double a=3.14;
6     int &b = a;
7     getchar();
8     return 0;
9 }
View Code

缘由:临时变量都是具备常量性质的,你不能使用一个变量去引用常量,这样有潜在改变常量的风险

代码1对应改为

1 #include<iostream>
2 
3 int main(int argc, char **argv)
4 {
5     const double a=3.14;
6     const int &b = a;
7     getchar();
8     return 0;
9 }
View Code

代码2对应改为

1 #include<iostream>
2 
3 int main(int argc, char **argv)
4 {
5     double a=3.14;
6     const int &b = a;
7     getchar();
8     return 0;
9 }
View Code

就没问题了。

相关文章
相关标签/搜索