引用和引用变量
变量必须初始化,且必须引用一块合法内存
int &c;//错误
但在类里面,可以这么定义,要用构造函数初始化
int a = 10;
int &c = a;//合法
int &c = 10;//非法,必须引用一块合法内存
const int &c = 10;//合法,不可修改c的值
常量引用
const int &c = 10;//合法,但不可修改c的值-->int temp = 10; const int &c = temp;
void test(const int& v) //防止修改入参
{}
一旦引用一个实体,再不能引用其他实体
int a = 10, b = 20;
int &c = a;
c = b;//合法,但这是赋值操作,a和c都变为20
一个变量可以有多个引用
int a = 10;
int &c = a;
int &b = a;
引用的本质-指针常量
int &ref = a;
-->
int * const ref = &a; //const修饰指针ref,表示指针的指向是固定的
引用做函数的返回值
不要返回局部变量的引用
int & retA()
{
int a = 10;
return a; //编译器可能会保留a的数据,但是函数结束后a的内存释放,再操作这块内存是非法的
}
函数调用可以作为左值
如果函数返回值为引用,则函数返回值可以作为左值
int & retA()
{
static int a = 10; //合法,全局数据区,可以返回它的引用
return a;
}
int main()
{
int &ref = retA();
cout<<ref<<endl;//10
cout<<ref<<endl;;//10
retA() = 1000;
cout<<ref<<endl; //1000
cout<<ref<<endl; //1000
}
引用变量作为类成员变量
引用成员变量 并不为这个变量新辟空间,必须提供构造函数,且要用初始化列表,形参也须是引用类型
常量变量:必须通过构造函数参数列表进行初始化。
引用变量:必须通过构造函数参数列表进行初始化。
普通静态变量:要在类外通过"::“初始化。
静态整型常量:可以直接在定义的时候初始化。
静态非整型常量:不能直接在定义的时候初始化。要在类外通过”::"初始化。
#include <iostream>
using namespace std;
class A {
public:
A(int &x1,int z1) :x(x1), y(z), z(z1) {} //x,y仅能在初始化列表中进行初始化;
void print() { printf("[%d,%d,%d]\n", x, y, z); }
int &getx() { return x; }
void setx(int &x1) { x = x1; }
int &gety() { return y; }
void sety(int &y1) { y = y1; } //初始化列表里,y是z的引用,改变y就是改变z
int getz() { return z; }
void setz(int z1) { z = z1; } //改变z也是改变y
private:
int &x;
int &y;
int z;
};
int main() {
int x = 10, y = 20, z = 30;
int x1 = 1, y1 = 2, z1 = 3;
int &b1 = x1, &b2 = y1;
A a(x,z);
a.print(); //[10,30,30]
a.setx(b1);
printf("x=%d\n",a.getx()); //x = 1
a.print(); //[1, 30, 30]
a.sety(b2); //y = 2
printf("y=%d\n", a.gety());//[1, 2, 2]
a.print();
a.setz(z1); //z = 3
printf("z=%d\n", a.getz());//[1, 3, 3]
a.print();
}
interesting
struct Foo
{
int a;
int b;
int c;
};
struct Bar
{
Foo& foo;
};
void test2()
{
cout<<"sizeof(Foo) = "<<sizeof(Foo)<<endl;
cout<<"sizeof(Bar) = "<<sizeof(Bar)<<endl;
cout<<"sizeof(Bar::foo) = "<<sizeof(Bar::foo)<<endl;
}
output:
sizeof(Foo) = 12
sizeof(Bar) = 8
sizeof(Bar::foo) = 12 //interesting!sizeof(Bar::foo)>sizeof(Bar)