#include <iostream>
using namespace std;
/*
*引用(References)类型
*这是C++语言的一个特殊的数据类型描述,用于在程序的不同部分使用两个以上的变量
*指向同一个地址,使得对其中任一个变量的操作实际上都是对同一地址单元进行的。
*在这种两个以上变量名的关系中,被声明为引用类型的变量名称之为实变量的别名。
*语法格式:
*类型名 & 引用型函数名或变量名=前已经声明的(常)变量名;
*e.g.
*int i;
*int &j=i;
*j=1;
*例中的j和i指向同一个地址单元,改变j的值也就改变了i的值
*/
void Test1()
{
int i=0;
int &j=i,k=2;
j++;
k++;
cout << &i << "->" << i << endl;
cout << &j << "->" << j << endl;
cout << &k << "->" << k << endl;
/*
*0x28fe98->1
*0x28fe98->1
*0x28fe94->3
*/
/*
*出现在变量声明语句中的'&'代表符号右端是别名。而在可执行语句中
*'&'则是取变量的地址。对于指针的使用引用类型时则要注意书写格式
*int i=0,*j&i,*&k=j;
*cout << *k;
*切不可写成下面的样子:
*int i,*p;
*int &r1=p;//非法语句
*int &r2=&i;//非法语句
*由于引用类型所声明的变量不是独立内存实体,所以不用用以对常数声明。如:'int &r=3'的形式就是错误的。
*
*引用类型都被放在同一程序块中,引用类型通常被用于主子函数间互相传递大量数据的设计中
*从而减少大量数据经过堆栈的复制。而在C语言中,主子函数若要对非全局变量实施写操作时,只能通过传递实形参的指针来实现。
*直接使用指针很容易造成地址溢出的错误。而用C++语言编制的同类程序中可以使用引用类型使得传递的实参,形参都指向同一个内存地址,
*减少了大量数据经过堆栈的复制,又避免了地址溢出的错误的发生。
*/
/*
*常量类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的。因此,定义或说明常类型时必须进行初始化。
*一般常量:
*在C语言中,const是保留字,是作为声明常数的数据类型的附加类别标识使用的,如'const int i=10;'.此时,被声明的常数必须到程序
*执行后,才能被访问。而在C++语言中,则允许被声明的常数在后续的编译中被直接访问。
*const int i=9;
*char str[i];//等效于char str[9];//此句在C++语言中是允许的:
*若在C语言中要实现这种技术,只能借助于#define i 9 来进行预定义进行常数子字符代换
*而#define 所预定义的常数的类型在编译时确实无法确定的。如果用#define 预定义的常数做实参数传递给另一个函数时,
*该函数只能按照声明的形式参数类型来做隐含类型转换。
*/
}
const int N = 3;
void print(const int *p, int n)
{
cout << "{" << *p;
for(int i=1;i<n;i++)
cout << "," << *(p+i);
cout << "}" << endl;
}
void Test2()
{
/*
*在C++面向对象程序设计中,指针和引用使用的较多,其中使用const修饰的常指针和常引用用的更多。
*使用常参数则表明该函数不会更新某个参数所指向或所引用的对象,这样,在参数
*传递过程中就不需要执行拷贝初始化构造函数,这将回改善程序的运行效率。
*/
int array[N];
cout << "Please input " << N << " integeters:" << endl;
for(int i=0;i<N;i++)
cin >> array[i];
print(array,N);
}
/*
*常成员函数
*使用const关键字进行说明的成员函数,称为常成员函数。只有常成员函数才有资格操作常量或者常量对象,
*使用const关键字说明的成员函数不能用来操作常对象。常成员函数 说明格式如下:
*<类型说明符> <函数名>(<参数表>) const;
*其中,const是加在函数说明后面的类型修饰符,它是函数类型的一个组成部分,因此,在函数实现部分也要带const关键字。
*/
class R
{
public:
R(int r1,int r2) { R1=r1;R2=r2; }
void print();
void print() const;
private:
int R1,R2;
};
void R::print() { cout << R1 << "," << R2 << endl; }
void R::print() const { cout << "I'm const! " << R1 << "," << R2 << endl; }
/*
*常数据成员
*类型修饰符const不仅可以说明成员函数,也可以说明数据成员。由于const类型对象必须被初始化,并且不能更新,因此,
*在类中说明了const数据成员时,只能通过成员初始化列表的方式来生成构造函数对数据成员初始化。
*/
class A
{
public:
A(int i);
void printA();
const int &r;//常int型引用
private:
const int a;//常int型变量
static const int b;//静态常int型变量
};
const int A::b = 10;
A::A(int i):a(i),r(a) { }
void A::printA() { cout << a << ":" << b << ":" << r << endl; }
int main()
{
Test1();
Test2();
R a(5,4);
a.print();
const R b(20,43);
b.print();
A a1(100),a2(0);
a1.printA();
a2.printA();
return 0;
}