引用的本质和C++类封装的原理, 谈到这个问题就要,首先连接长指针变量;即型如int * const p,他表示的是p的指向不可变,指向的内容可读可写;
int a = 10;
int * const p = &a;
*p = 20;
cout << *p << endl;
而如果使用const int *const p这样指针p就完全变为只读的,如;
int a = 10;
const int * const p = &a;
*p = 20;//编译器报错;
cout << *p << endl;
这个取地址和取内容全是自己手动操作的, 而引用是什么做法, 化繁为简, 将去地址和取内容自动化, 封闭起来看不到;
指针必须初始化的原因是,他的内部被const修饰,所以指针初始化不能赋值;
如;
int a = 10;
int & re = a; //等价于 int * const p = &a;即自动取地址, 编译器做的;不过这个p是内藏的,在汇编代码下能看到;相当于对用户封装;
re = 20;//等价 *p = 20;即他自动取内容运算;
所以他本质就是常指针, 封装了指针操作, 内部依然是指针, 只不过用户看不到, 以为就是变量别名;
下面要讲的封装的本质就和类的长指针有巨大关系;
我们先看一个列子;
class Test
{
public:
Test(int a)//Constructor;
: a(a)
{
}
int & GetA(void)//Get a data;
{
return this->a;
}
private:
int a;//only one member data;
};
int main(int argc, char ** argv)
{
Test t;
cout << t.GetA() << endl;
}
编译器会将它翻译成大致下面这样;
struct Test
{
int a;
};
void Test_Initialization(Test * const myThis, int a)
{
myThis->a = a;
}
int & Test_GetA(Test * const myThis)
{
return myThis->a;
}
int main(int argc, char ** argv)
{
Test t;
Test_Initialization(&t, 0);
cout << Test-GetA(&t) << endl;
}
这里你可以看到, 在通过变量名调用函数是通过编译器贩子将对象(即C语言中的结构体变量)的地址自动以长引用的方式传递的, 这里你大致可以感觉到类封装的本质就是在将结构体穿个马甲, 通过桥梁常指针将其连接起来, 也知道,为什么类中函数不占用大小,只有成员变量有大小;
类封装将引用中内涵指针变量释放出来给用户, 即是this指针, 这里你也知道了传来的this指针为什只能在成员函数后面加const修饰, 传来的this指针加const修饰不能返回成员变量的引用, 因为修饰后相当于const int * cosnt p, 变成只读变量,