一、什么是引用 引用是别名,创建引用时,务必要初始化为另一个对象,不能为空。 int &rSomeRef = someInt; 对rSomeRef的操作实际上就是对someInt的操作。 rSomeRef = 7; //somInt = 7 不能给引用重新赋值。 int someTwo = 9; rSomeRef = someTwo; //实际上rSomeRef还是指向的是someInt这个对象。 指针可以为空,但是引用不能为空。 混合定义引用和其他变量时应该分开 Cat &rfirst, second; //这里rfirst是引用,second是变量 最好写成: Cat &rfirst; Cat second; 二、按引用传递函数参数 使用引用的语法与使用指针的语法不同,但是效果一样:不是创建一个作用域为整个函数的副本,而是相当于让函数能够访问原始对象。 1.使用引用实现swap(). #include <iostream> using namespace std; void swap(int &x, int &y); void swap(int &x, int &y) { int tmp; tmp = x; x = y; y = tmp; } int main() { int x = 5, y = 10; swap(x, y); cout<<x<<endl; cout<<y<<endl; return 0; } 2.按引用传递以提高效率 按值将对象传递给函数时, 都将创建该对象的一个副本,而按值从函数返回 一个对象时,将创建另一个副本。 对于大型的对象(如结构或类对象),复制的开销可能很高。每当创建这些临时副本时,都要调用一个特殊的构造函数:复制构造函数。函数返回时,临时对象将被销毁,这将调用对象的析构函数。 3.传递const指针 如果使用按地址传递对象,但是不允许做任何修改,这是可以使用const来修饰指针。同时也可以修饰引用。
#include <iostream> using namespace std; class SimpleCat { public: SimpleCat(); SimpleCat(SimpleCat&); ~SimpleCat(); int getAge() const { return itsAge;} void setAge(int age){itsAge = age;} private: int itsAge; }; SimpleCat::SimpleCat() { cout<<"Simple Cat Constructor..."<<endl; itsAge = 1; } SimpleCat::SimpleCat(SimpleCat&) { cout<<"Simple Cat Copy Constructor..."<<endl; } SimpleCat::~SimpleCat() { cout<<"Simple Cat Copy Destructor..."<<endl; } const SimpleCat & functionTwo(const SimpleCat & theCat) { cout<<"function Two returnning...."<<endl; cout<<"frisky is now " <<theCat.getAge() << "years old" <<endl; //theCat.setAge(8); //const return theCat; } int main() { SimpleCat frisky; int age = 5; frisky.setAge(age); functionTwo(frisky); return 0; }
注意:由于functionTwo被指向的对象时const,因此不能调用非const方法setAge。如果不将theCat.setAge(8);这行注释掉,是不能编译过的。 4.何时使用引用和指针 相对指针来说,更多C++程序员喜欢使用引用,然而引用不能被重新赋值,如果需要首先指向一个对象,然后再指向另一个对象,就使用指针。 第二种情况是使用new运算符来创建对象,如果 new返回空,引用将可能为空。所以安全的做法如下: int pInt = new int; if(pInt != NULL) int &rInt =*pInt;