c++引用

来源:互联网 发布:windows hello 不可用 编辑:程序博客网 时间:2024/04/30 20:42

   C++中的引用思想来源于 Algol 。在C++中,引用是支持运算符重载的基础,也为函数参数的传入传出控制提供了便利。


    使用引用时候的一些规则:
        1)当引用被创建时,它必须被初始化(指针可以在任何时候被初始化)。
        2)一旦一个引用被初始化指向一个对象,他就不能改变为另一个指针。(指针可以在任何时候只想另     一个对象。void *特殊考虑)。
      3)不可能有NULL引用。它必须保证引用是和一块合法的存储单元关联。
    引用的初始化:
        当引用的初始化是一个一个左值的时,其初始化是非常简单的事情。对“普通” T& 的初始式必须是一     个类型为 T 的左值。对一个const T& 的初始式不必是一个左值,甚至可以不是类型T的;在这种情况下:
         1)需要应用到 T 的隐式类型转换。
         2)将结果存入一个类型T的临时变量。
         3)将这个临时变量用作初始式的值。例如:
            
             double& dr=1;        //error: 要求左值
             const double& cdr =1;//ok
             对后一个的解释是:
             double temp = double(1);//首先建立一个临时变量
             const double& cdr=temp; //临时变量作为cdr的初始式的值  
    引用的使用:
       1.引用就像是能自动被编译器引用的常量性指针。通常用于函数的参数传递和返回值。
        1)函数传值。例如:
             1>非常量引用:
             void increment(int& a){ a++;}
             int x=1;
             increment(x);
             2>常量引用
             increment (1);//error,increment函数参量必须是非常量,不能改变。
             2>当函数参数为常量引用时,
             如果知道函数不妨害对象的不变性的话,让这个参数是一个常量引用将允许这个函数在任何时候         使用。这就意味着,对于内部类型,这个函数将不会改变参数,而对于用户自定义类型来说,这个函          数只能调用常量成员函数。例如:
             int noIncrement(const int& a){
                                            return a;                     
                                         }
             noIncrement(1);//OK
             class A {
                        int a;
                        public:
                        A(int i):a(i){}
                        const int getA() const {return a;}
                      }
              const int constGet(const A& a){return a.getA();}
              当然,在使用常量引用的时候特别注意,我们的函数也许会接受临时对象,这个临时对象是有另               一个函数的返回值创立或有用户显示的创立。临时对象总是不能改变的,因此,如果,不使用常               量引用,参数将不会被编译器接受。例如:
              noIncrement(new A(1));
              3>指针引用
                 在C语言中,改变指针本身,函数申明可以像这样:
                 void f(int **);
                 当传递它时,必须知道指针的地址:
                 int i=47;
                 int *p=i;
                 f(&p);
                 在C++中,语法清晰很多。函数参数变成指针的引用,用不着取指针的地址。
                 void (int *&){i++;}
                 int *i=0;
                 f(i);
           总结参数传递的规则:
                 传值方式尽量用常量引用,当不想改变参数时。因为,如果采用值传递的方式,会调用构             造,析构函数。
        2)返回值:
            从函数中返回一个引用,必须像返回一个指针一样对待。当函数返回时,无论引用关联的是什么都         应该存在,否则,将不知道指向哪一个内存。
            一般情况,局部对象不能返回引用类型。返回引用一般用在成员函数的返回里面,如运算符重载的         成员版本,或者参数是个外部对象。
        int & h(){int q=0;
                   return q//error q是局部对象。
                  }
        class A{
                
                public :
                int a;
                A(int i):a(i){}
                A& (int i,int j){ a=i+h;
                    return this;}
                friend A& operator+(A& left,A& right);
               };
            A& operator+(A& left ,A& right){
                                               left.a+=right.a;
                                               return left;
                                            }
    2.指向成员的指针
      普通的指针 *p=4;
      指向对象的指针 ->*,对于一个对象或引用,则为  .*  如下所示。
      objectPointer->*pointToMember=47;
      objectPointer.*pointToMember=47;
      pointToMember语法? 它像任何一个指针。必须说明它的类型,使用中也必须带一个*,唯一的区别,就是必须说明这个成员指针使用什么类型的对象。当然,这是使用类名和作用域运算符来实现的。如
     int ObjectClass::*pointToMember;
      定义一个   pointToMember 的成员指针  ,类型为int。还可以在定义的时候初始化这个成员指针。
     int ObjectClass::*pointToMember=ObjectClass::a;
     class Data{
                public:
                     int a,b,c;
                   } ;
      int main(){
                    Data d,*dp=&d;
                    int Data::*pmInt=&Data::a;
                    dp->pmInt=47;