顺序容器访问成员函数返回的是引用
即front、back、下标和at 返回的是引用
这里以front成员函数为例,找到front的源码
/**
* Returns a read/write reference to the data at the first
* element of the %vector.
*/
reference
front() _GLIBCXX_NOEXCEPT
{ return *begin(); }
/**
* Returns a read-only (constant) reference to the data at the first
* element of the %vector.
*/
const_reference
front() const _GLIBCXX_NOEXCEPT
{ return *begin(); }
以上代码表明了:
- front成员函数的返回值是reference 可以直接顾名思义 就是引用
我们从源码中追根溯源 这里的reference是__gnu_cxx作用域中在__alloc_traits<_Tp_alloc_type>类中定义的别名
typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Alloc_traits;
typedef typename _Alloc_traits::reference reference;
typedef value_type& reference; //reference是value_type的引用类型
- 成员函数front有两个,其中一个是const的 即如果容器是一个const对象,则调用const的成员函数,返回的是const 的 引用
- front的其实直接调用的就是begin成员方法,直接对其解引用返回即可
还需要补充的一点是:
vector<int>c(10,0);//随便定义一个全0的大小为10的vector
if(!c.empty()){
c.front()=42; //因为是引用,则可以直接改变
auto &r =c.back();
r=1; // 可以改变
auto r2 =c.back();
r2=1; //不可改变
}
这里需要注意的是 c.back返回的是引用 但是r2 却无法更改c中元素的值 是因为r2其实是int类型的 而r才是int的引用类型
切记不要把r理解为引用的引用 因为引用不是对象 是不能定义引用的引用的。
我们会看auto 可以发现 auto 有如下说明:
**当引用被用作初始值时,真正参与初始化的其实是引用对象的值。此时编译器以引用对象的类型作为auto的类型
例如:
int i=0,&r=i;
auto a =r; //这里a是一个整数,而不是整数的引用
同时说明的是 auto会忽略掉顶层const 而底层const 会保留下来。