zoukankan      html  css  js  c++  java
  • C++ this指针 全部

         在每一个成员函数中都包含一个特殊的指针,这个指针的名字是固定的。叫做this。它是指向本类对象的指针,它的值是当前被调用的成员函数所在的对象的起      始地址。例如:当调用成员函数a.volume时,编译系统就把对像a的起始地址赋给this指针,于是在成员函数引用数据成员时,就按照this的指向找到对象a的数      据成员。例如volume函数要计算height*width*length的值,实际上是执行:

                      (this->height)*(this->width)*(this->length);

         由于当前this指向对象a,因此相当于执行:

                      (a.height)*(a.width)*(a.length);

         this指针是隐式使用的,它是作为参数被传递给成员函数的。*this表示被调用的成员函数所在的对象,this*就是this所指向的对象,即当前的对象。例如:在        成员函数a.volume()的函数体中,如果出现*this,它就是本对象a。上面的语句可以使用下面的语句:

                      return((*this).height*(*this).width*(*this).length);

    常对象

          如果一个对象被声明为常对象,则不能调用该对象的非const型的成员函数(除了由系统自动调用的隐式的构造函数和析构函数)。例如:

                     const Time t1(10,15,36);                         //定义一个常对象t1,并指定数据成员的初值

                     t1.get_time();                                        //企图调用对象t1中的非const型的成员函数,非法。。。。

        怎么才能引用常对象中的数据成员呢?很简单,只需将该成员函数声明为const即可,如:

           void get_time() const;   //将函数声明为const;

        这就是常成员函数,常成员函数可以访问常对象中的数据成员,但是仍然后允许修改常对象中数据成员的值。如果一定修改常对象中的某个数据成员的值,ANSI C++考虑到实际编程的需要,对此进行了处理,对该数据成员声明为mutable,如:

        mutable int count;    把count声明为可变的数据成员,这样就可以用声明为const的成员函数来修改它的值。

    常数据成员

         只能通过构造函数的参数初始化表对常数据成员进行初始化。例如:

         Time::Time(int h)

        { hour=h;}

        这样做是非法的,常数据成员不能被赋值。下面这样是正确的:

        Time::Time(int h):hour{}

        在类体中声明了某个常数据成员后,该类所有对象中的该数据成员的值都是不能改变的,但是不同对象中该成员数据成员的值可以是不同的(在定义对象那时     给定)。

    常成员函数

         如果将成员函数声明为常成员函数,则只能引用本类中的数据成员,而不能修改它们,例如:

         void get_time() const;//注意const的位置在函数名和括号之后; 

         const是函数类型的一部分,在声明函数和定义函数时都要有关键字const,在调用时不用加。常成员函数可以引用const数据成员,也可以引用非const的数据成员。const数据成员可以被const成员函数引用,也可以被非const的成员引用。

        记住:不要认为常对象中的成员函数都是常成员函数。常对象只保障其所有数据成员不被修改。如果在常对象中有成员函数没有加const声明,编译系统把它       作为非const成员函数处理。

    指向对象的常指针

        将指向对象的指针变量声明为const型,并使之初始化,这样指针值始终保持为其初值,不能改变,即其指向始终不变。如:

        Time t1(10,12,15),t2;                  //定义对象

        Time *const ptr1=&t1;                //const位置在指针变量名前面,规定ptr1的值是常值。

        ptr1=&t2;                                  //错误,ptr1不能改变指向。

        定义指向对象的常指针的一般形式:

        类名  *const 指针变量名=对象地址;

        注意:应在定义指针变量时使之初始化,如

                Time *const ptr1;//指定ptr1为指向Time类的指针变量

                ptr1=&t1;         //使之指向t1,产生编译错误,常指针不能被赋值

        什么时候需要使用指向对象的常指针?

        如果想将一个指针变量固定地与一个对象相联系(即该指针变量始终指向一个对像),可以将它指定为const型指针变量。

    指向常对象的指针变量

        定义指向常变量的指针变量的一般形式:

        const 类型名  *指针变量名;

        如果一个变量已经被声明为常变量,只能用指向常变量的指针变量指向它,而不能用一般的指针指向他。

        指向常变量的指针变量除了可以指向常变量外,还可以指向未被声明为const的变量,此时不能通过此指针变量改变该变量的值。

    常对象

         1.如果一个对象已经被声明为常对象,只能用指向常对象的指针变量指向他,而不能用一般的指针变量去指向它。

         2.如果定义了一个指向常对象的指针变量,并使它指向一个非const的对象,则其指向的对象是不能通过指针来改变的。

               Time t1(10,12,15);                 //定义Time类对象t1,它是非const型对象

               const Time *p=&t1;               //定义p是指向常对象的指针变量,并指向t1

               t1.hour=18;                         //正确,t1不是常变量

               (*p).hour=18;                         //错误,不能通过指针变量改变t1的值。

          3.指向常对象的指针最常用于函数的形参,目的是在保护形参指针指向的对象,使它在函数执行过程中不被修改。如

               int main()

              {

                   void fun(const Time *p);  //形参是指向常对象的指针变量

                   Time t1(10,12,30);          //定义Time类对象t1,他不是常对象

                   fun(&t1);                       //实参是对象t1的地址

                   return 0;

              }

              void fun()

             {

                   p->hour=18;                   //错误

                   cout<<p->hour<<endl;

             }

    对象的常引用

         一个变量的引用就是变量的别名。实际上,变量名和引用名都是用同一段内存单元。

    #include <iostream>
    using namespace std;
    class Time
    {
    public:
    Time(int,int,int);
    int hour;
    int minute;
    int sec;
    };

    Time::Time(int h,int m,int s)
    {
    hour=h;
    minute=m;
    sec=s;
    }

    void fun(Time &t)
    {t.hour=18;}

    int main()
    {
    Time t1(10,13,56);
    fun(t1);
    cout<<t1.hour<<endl;
    return 0;
    }

    对象的动态建立

          如果已经定义了一个Box类,可以用下面的方法动态建立一个对象:

          new Box;

          用new运算符动态的分配内存后,将返回一个指向新对象的指针的值,即所分配的内存空间起始地址。用户可以获得这个地址,并通过这个地址来访问这         个对象,需要定义一个指向本类的对象的一个指针变量来存放改地址。如:

           Box *pt;               //定义一个指向Box类对象的指针变量pt

           pt=new Box;         //在pt中存放了新建对象的起始地址

          在程序中,可以通过pt访问这个新建的对象,

           cout<<pt->height;          //输出该对象的height成员

           cout<<pt->volume();        //调用该对象的volume函数,计算并输出体积

          C++还允许在执行new时,对新建的对象进行初始化,如

           Box *pt=new Box(12,15,55);

          调用对象既可以通过对象名,也可以通过指针,用new建立的动态对象一般是不用对象名的,而是通过指针访问的。它主要用于动态的数据结构,如链表。

          在执行new运算符时,如果内存量不足,无法开辟所需的内存空间。目前大多数C++编译器都会使new返回一个0指针值。只要检测返回值是否为0,就可以       分配内存是否成功

  • 相关阅读:
    《C++ Primer Plus》15.1 友元 学习笔记
    《C++ Primer Plus》14.4 类模板 学习笔记
    《C++ Primer Plus》14.3 多重继承 学习笔记
    《C++ Primer Plus》14.2 私有继承 学习笔记
    《C++ Primer Plus》第13章 类继承 笔记
    继承和动态内存分配——需要为继承类定义 显式析构函数、复制构造函数和赋值运算符
    C++中的抽象基类示例
    C++ 在继承中使用virtual
    《C++ Primer Plus》第12章 类和动态内存分配 学习笔记
    《C++ Primer Plus》12.7 队列模拟 学习笔记
  • 原文地址:https://www.cnblogs.com/NongSi-Net/p/4257226.html
Copyright © 2011-2022 走看看