精华内容
下载资源
问答
  • 2022-03-04 12:34:44


    一、this指针的引入

    class Date{
    public:
    	void Display()
    	{
    		cout << _year << "-" << _month << "-" << _day << endl;
    	}
    
    	void SetDate(int year, int month, int day)
    	{
    		_year = year;
    		_month = month;
    		_day = day;
    	}
    private:
    	int _year;
    	int _month;
    	int _day;
    };
    
    int main()
    {
    	Date d1, d2;
    	d1.SetDate(2022, 3, 4);
    	d2.SetDate(2022, 3, 5);
    	d1.Display();
    	d2.Display();
    	return 0;
    }
    

    对于上述类,有这样的一个问题:
    Date类中有SetDate与Display两个成员函数,函数体中没有关于不同对象的区分,那当s1调用SetDate函数时,该函数是如何知道应该设置d1对象,而不是设置d2对象呢?
    C++中通过引入this指针解决该问题,即:C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有成员变量的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。

    二、this指针的特点

    1. this指针是成员函数第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递

    2. this指针的类型:类类型* const
    例如对于Data类来说,无论是Display(),SetDate(int year, int month, int day)以及其它的成员函数,都会隐藏一个Date* const this的参数(成员函数默认的第一个参数)。当我们去调用成员函数Display()时,编译器最终会理解为Display(Date* const this)

    3. this指针本质上其实是一个成员函数的形参,是对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针

    4. 只能在“成员函数”的内部使用
    全局函数,静态成员函数中的形参不隐藏(不含有)this指针

    5. this 指针在成员函数的开始前构造,在成员函数的结束后清除,生命周期和其他函数参数一样

    三、this指针放在哪里?this指针可以为空吗?

    1.this指针存在哪里?

    其实编译器在生成程序时加入了获取对象首地址的相关代码。并把获取的首地址存放在了寄存器ECX中(VC++编译器是放在ECX中,其它编译器有可能不同)。也就是成员函数的其它参数正常都是存放在栈中。而this指针参数则是存放在寄存器中。类的静态成员函数因为没有this指针这个参数,所以类的静态成员函数也就无法调用类的非静态成员变量。

    2.this指针可以为空吗?

    可以为空,当我们在调用函数的时候,如果函数内部并不需要使用到this,也就是不需要通过this指向当前对象并对其进行操作时才可以为空(当我们在其中什么都不放或者在里面随便打印一个字符串),如果调用的函数需要指向当前对象,并进行操作,则会发生错误(空指针引用)就跟C中一样不能进行空指针的引用

    ——来自转载

    四、注意

    每个成员函数(包括构造函数和析构函数)都有一个隐藏的this指针。this指针指向的是调用成员函数的对象。如果方法需要引用整个调用对象,则可以使用表达式*this。如果在编写一个成员函数时,不需要或者为了防止修改该对象的值时,可以在函数的括号后面使用const限定符修饰this指针,这样就不能通过this指针来修改对象的值。
    对于成员函数的返回值,一般不返回this,因为this是该对象的地址,并不是对象本身。*this(将解引用运算符 * 用于this,将得到指针指向的值)才是对象本身

    更多相关内容
  • this指针只能在一个类的成员函数中调用,它表示当前对象的地址。下面是一个例子: 代码如下: void Date::setMonth( int mn ) { month = mn; // 这三句是等价的 this->month = mn; (*this).month = mn; } 1. this...
  • 要想理解 C++ 的 this 指针,我们先把下面的 C++ 代码转换成 C 的代码 class Car { public: int m_price; // 成员变量 void SetPrice(int p) // 成员函数 { m_price = p; } }; int main() { Car car; car....
  • C++中this指针用法详解及实例 概要: 本文简单介绍this指针的基本概念,并通过一个实际例子介绍this指针用于防止变量命名冲突和用于类中层叠式调用的两个用法。 this指针概览 C++中,每个类 对应了一个对象,每个...
  • C++ this 指针详解 学习 C++ 的指针既简单又有趣。通过指针,可以简化一些 C++ 编程任务的执行,还有一些...全局仅有一个this指针,当一个对象被创建时,this指针就存放指向对象数据的首地址。 class Ctest { publi
  • 主要介绍了C++编程指向成员的指针以及this指针的基本使用指南,与C语言一样,存储的数值被解释成为内存里的一个地址,需要的朋友可以参考下。
  • 主要介绍了C#中this指针的用法,对初学者而言是非常重要的概念,必须加以熟练掌握,需要的朋友可以参考下
  • 主要介绍了详解C++中的this指针与常对象,是C++入门学习中的基础知识,需要的朋友可以参考下
  • c++友元类与this指针

    千次阅读 2022-03-21 12:15:11
    } this指针在类外是不存在的,并且每定义一个对象,该对象所对应的地址和this指针所指的地址都是一样的,这就保证了定义多个对象的时候,都可以通过this指针来准确定位来进行操作 class GG { public: GG(string ...

    友元

    友元, friend描述的关系。友元只是提供一个场所,赋予对象具有打破类的权限定(无视权限)

    • 友元函数

      • 普通友元函数

      • 以另一个类的成员函数充当友元函数,顺序如下:

        • B 类

        • A 类

        • A类的友元函数(B类的成员函数)

    • 友元类 

    友元函数 

    普通友元函数 

    •  友元函数,可以打破限定去访问类中的数据成员,有一定程度的打破类的封装性
    • 通俗点讲就是,你的女朋友就是我的女朋友,我的女朋友还是我的女朋友,有点白嫖的感觉

     

    •  友元函数是不属于类,所有类的限定词是管不住它的
      class MM
      {
      public:
      	MM(string name, int age) :name(name), age(age) {}
      	void print()
      	{
      		cout << name << "\t" << age << endl;
      	}
      	friend void printData1(MM& mm);
      protected:
      	string name;
      	friend void printData2(MM& mm);
      private:
      	int age;
      	friend void printData3(MM& mm);
      };
      //不需friend修饰,不需要类名限定
      //不论友元函数放在哪个限定词下都不会影响它的使用
      void printData1(MM& mm)
      {
      	cout <<"我是共有属性的 " << mm.name << "\t" << mm.age << endl;
      }
      void printData2(MM& mm)
      {
      	cout <<"我是保护属性的" << mm.name << "\t" << mm.age << endl;
      }
      void printData3(MM& mm)
      {
      	cout <<"我是私有属性的" << mm.name << "\t" << mm.age << endl;
      }
      int main()
      {
      	MM mm("美女", 18);
      	mm.print();
      	printData1(mm); //友元函数的调用也不需要对象来调用
      	printData2(mm); //与普通的函数调用是一样的
      	printData3(mm); //但是普通函数不能访问类中的数据成员
      	/*打印结果
      	美女    18
          我是共有属性的 美女     18
          我是保护属性的美女      18
          我是私有属性的美女      18
      	*/
      	return 0;
      }
    • 而且我们还可以看到这个函数在类外实现的时候不需要如何修饰词,仿佛根本就与类毫无关系,但是却是肆无忌惮的把类中的数据成员给看的清清楚楚,类在它面前变得一丝不挂   

    • 要注意,友元函数既可以在类中实现,也可以在类外实现,但是可能编译器版本不同会有所差异,我们只需要在类外声明一下这个友元函数即可
    •  友元函数只是提供一个场所,让对象无视权限,并不代表它可以为所欲为,也不会改变原有的权限
      class MM 
      {
      public:
      	MM(string name, int age) :name(name), age(age) {}
      	void print() 
      	{
      		cout << name << "\t" << age << endl;
      	}
      	friend void printData() 
      	{
      		//不属于类,不能直接访问成员
      		cout << name << "\t" << age << endl;
              //这样是错误,它不能直接访问数据成员
      		//友元函数提供一个场所,让对象无视权限
      
      	}
      protected:
      	string name;
      private:
      	int age;
      };

       

    以另一个类的成员函数充当友元函数 

    • 这个就需要大家牢记上面的那个顺序写法,如果不按照那个顺序来写,可能会发生报错
      class B      //B类
      {
      public:
      	void printA();
      	void printData();
      protected:
      };
      
      class A    //A类
      {
      public:
      	friend void B::printA();  //先把B中的printA作为A类的友元函数
      protected:
      	string name = "A";
      };
      //成员函数实现,一定是在另一个类的下面实现
      void B::printA()
      {
      	A a;
      	cout << a.name << endl;
      }                           //这里就可以看出来是否为友元函数的区别
      void B::printData()
      {
      	A a;
      	//错误 ,该函数不是A类的友元函数,所以不能访问保护和私有属性
      	cout << a.name << endl;
      }
      int main()
      {
      	B b;
      	b.printA();
      /* 打印结果  A */
      	return 0;
      }
       

     

    友元类 

     

    class MM
    {
    	friend class GG;   //把GG作为MM的友元类
    public:
    	MM(string name, int age) :name(name), age(age) {}
    	void print() {
    		cout <<"我是通过MM对象输出的 " << name << "\t" << age << endl;
    	}
    protected:
    	string name;
    	int age;
    };
    class GG
    {
    public:
    	void print()    //就可以定义函数来访问MM中的数据成员
    	{
    		MM mm("mm", 18);
    		cout <<"我是通过GG对象无参输出的 " << mm.name << "\t" << mm.age << endl;
    	}
    	void printMM(MM& mm)   //也可以通过传参的方式访问
    	{
    		cout <<"我是通过GG对象传参输出的 " << mm.name << "\t" << mm.age << endl;
    	}
    protected:
    };
    
    int main()
    {
    	MM mm("mm", 18);
    	mm.print();
    	GG gg;
    	gg.print();
    	gg.printMM(mm);
    	/*打印结果
    	我是通过MM对象输出的 mm 18
        我是通过GG对象无参输出的 mm     18
        我是通过GG对象传参输出的 mm     18
    	*/
    	return 0;
    }

    总的来说,友元函数和友元类还是比较好理解的,友元就相当于是交朋友的意思,我们都已经是好朋友的,就应该有福同享,有难待会再说 ,所以就可以打破权限访问

     

    this指针与explicit

    • explicit修饰构造函数使用,不让隐式转换构造

    • this指针

      • 避免形参名和数据成员同名,通指对象的地址

      • 充当函数返回值,返回对象自身,用*this表示对象本身

      • 静态成员函数中是不能使用this指针

     explicit

    • 它可以修饰构造函数,被修饰之后就不可以在用隐式转换 
      class MM
      {
      public:
      	explicit MM(int age) :age(age) {}
      	void print()
      	{
      		cout << age << endl;
      	}
      protected:
      	int age;
      };
      int main()
      {
      	//explicit 不让隐式转换构造
      	//MM mm = 12;
      	//MM temp = 1.33; 等号的隐式转换来赋值就会报错
      	MM temp(12);
      	temp.print();
      
      	/*打印结果
      	12
      	*/
      	return 0;
      }

     this指针

    当我们在写构造函数的时候,不想用或者不能用初始化参数列表的时候,又不想去找一个好的形参名的时候,我们为了区分数据成员和形参,就可以用类名限定或者this指针 

    class GG
    {
    public:
    	GG(string name, int age) :name(name), age(age) {}
    	//普通函数不存在初始化参数列表
    	void initData(string name, int age)
    	{
    		//类名限定 帮助计算机去识别,下面两种效果是一样的
    		GG::name = name;
    		this->age = age;
    	}
    	void print()
    	{
    		cout << this->name << " " << this->age << endl;
    	}
    protected:
    	string name;
    	int age;
    };
    int main()
    {
    	GG gg("吴彦祖", 28);  //初始化参数列表赋值
    	gg.print();          
    	gg.initData("周杰伦", 38);  //自定义构造函数赋值
    	gg.print();
    	/*打印结果
    	吴彦祖 28
        周杰伦 38
    	*/
    	return 0;
    }
    • this指针在类外是不存在的,并且每定义一个对象,该对象所对应的地址和this指针所指的地址都是一样的,这就保证了定义多个对象的时候,都可以通过this指针来准确定位来进行操作
      class GG
      {
      public:
      	GG(string name, int age) :name(name), age(age) {}
      	//普通函数不存在初始化参数列表
      	void printThis()
      	{
      		cout << this << endl;
      	}
      protected:
      	string name;
      	int age;
      };
      int main()
      {
      	GG gg1("吴彦祖", 28); 
      	GG gg2("周杰伦", 30);
      	cout << &gg1 << endl;
      	gg1.printThis();
      	cout << &gg2 << endl;
      	gg2.printThis();
      	/*打印结果
      	00F3F878
          00F3F878
          00F3F850
          00F3F850
      	*/
      	return 0;
      }

    • this指针还可以充当返回值,返回的是类的本身,*this就是类本身(这里就可以说明,this指针的就是一个指向类的指针,只不过它不需要定义,出了类就不存在)
    class GG
    {
    public:
    	GG(string name, int age) :name(name), age(age) {}
    	void print()
    	{
    		cout << this->name << " " << this->age << endl;
    	}
    	GG& returnGG()
    	{
    		return *this;
    	}
    protected:
    	string name;
    	int age;
    };
    int main()
    {
    	GG gg("哥哥吴彦祖", 38);
    	gg.returnGG().returnGG().returnGG().returnGG().returnGG().returnGG().print();
    	/*打印结果
    	哥哥吴彦祖 38
    	*/
    	return 0;
    }
    • 这里的gg.returnGG()就是返回gg,后面的以此类推

     

     总之,友元和this指针的点比较简单,容易理解,但是他们的用处却是比价重要,需要我们牢记和经常性的去使用

    展开全文
  • C++经典问题_04 静态成员和this指针

    千次阅读 2022-03-24 15:46:28
    this指针 ① 为什么需要this指针this指针的用途 ③ this指针使用的时候注意事项 一. 静态成员 ① 静态成员变量 静态成员变量就是普通的成员变量前面加上static关键字就是静态成员变量. 所有的对象共享同一份...

    一. 静态成员

    ① 静态成员变量

    静态成员变量就是普通的成员变量前面加上static关键字就是静态成员变量.

    1. 所有的对象共享同一份静态成员变量.
    2. 在编译阶段分配内存,存储在全局数据区
    3. 在类内声明,类外初始化,需要在类外单独分配空间.
    4. 生命周期不依赖任何的对象,为程序的整个生命周期.
    5. 即可以通过对象来访问,也可以通过类名来访问
    /*----------------------------------------------------------------
    * 项目: Classical Question
    * 作者: Fioman
    * 邮箱: geym@hengdingzhineng.com
    * 时间: 2022/3/22
    * 格言: Talk is cheap,show me the code ^_^
    //----------------------------------------------------------------*/
    
    #include <iostream>
    using namespace std;
    class Simple
    {
    public:
    	Simple()
    	{
    		mSimpleCountPrivate++;
    		cout << "Simple的构造函数被调用,已被构造的次数" << ++mSimpleCount << endl;
    	}
    	~Simple() {};
    
    	int  get_obj_count(void)
    	{
    		return mSimpleCountPrivate;
    	}
    
    public:
    	static int mSimpleCount;
    
    private:
    	static int mSimpleCountPrivate; // 私有的静态成员变量,外部不能直接访问
    };
    
    int Simple::mSimpleCount = 0; // 类的静态成员变量需要在类外分配内存空间
    int Simple::mSimpleCountPrivate = 0; 
    
    
    int main()
    {
    
    	Simple s1; // 第一次构造
    	cout << "已经创建的对象的个数: " << Simple::mSimpleCount << endl;
    	Simple s2; // 第二次构造
    	cout << "已经创建的对象个数: " << s2.get_obj_count() << endl;
    	Simple s3; // 第三次构造
    	cout << "已经创建的额对象个数: " << s3.mSimpleCount << endl;
    	system("pause");
    	return 0;
    }
    

    结果:

    ② 静态成员函数

    1. 普通的函数前面加上static关键字就是静态成员函数
    2. 静态成员函数没有this指针,所以只能访问静态成员变量
    3. 所有的对象共享静态成员函数,无论对象是否已经创建,都可以访问静态成员函数
    4. 静态成员函数,不能调用普通的成员函数,只能调用静态的成员函数
    5. 普通的成员函数有this指针,可以访问内部的任意成员,而静态成员函数没有this指针,只能访问静态成员(静态成员变量和静态成员函数)
    /*----------------------------------------------------------------
    * 项目: Classical Question
    * 作者: Fioman
    * 邮箱: geym@hengdingzhineng.com
    * 时间: 2022/3/22
    * 格言: Talk is cheap,show me the code ^_^
    //----------------------------------------------------------------*/
    
    #include <iostream>
    using namespace std;
    class Student
    {
    public:
    	Student(const char *name, int age, float score)
    	{
    		mName = name;
    		mAge = age;
    		mScore = score;
    		mTotal++;
    		mScores += mScore;
    	}
    	void show()
    	{
    		cout << mName << "的年龄是: " << mAge << ", 成绩是: " << mScore << endl;
    	}
    
    	static int get_total()
    	{
    		return mTotal;
    	}
    	static float get_scores()
    	{
    		return mScores;
    	}
    private:
    	const char *mName;
    	int mAge = 0;
    	float mScore;
    	static int mTotal; // 总人数
    	static float mScores; // 总分数
    };
    // 定义静态成员变量
    int Student::mTotal = 0;
    float Student::mScores = 0.0;
    
    int main()
    {
    	(new Student("张三", 15, 100))->show();
    	(new Student("李四", 13, 89))->show();
    	(new Student("王五", 12, 100))->show();
    	(new Student("小明", 11, 82))->show();
    
    	int total = Student::get_total();
    	float scores = Student::get_scores();
    	cout << "当前共有" << total << "名学生,总成绩是" << scores << ", 平均分是: " << scores / total << endl;
    
    	system("pause");
    	return 0;
    }
    

    结果:
    在这里插入图片描述

    二. 成员变量和成员函数分开存储

    ① 空对象占用字节的大小

    在C++中,类内的成员变量和成员函数分开存储,只有非静态成员变量才属于类的对象上.
    而一个空类它也是占用字节的,占用1个字节.

    /*----------------------------------------------------------------
    * 项目: Classical Question
    * 作者: Fioman
    * 邮箱: geym@hengdingzhineng.com
    * 时间: 2022/3/22
    * 格言: Talk is cheap,show me the code ^_^
    //----------------------------------------------------------------*/
    
    #include <iostream>
    using namespace std;
    class Empty
    {
    	// 空类什么都没有
    };
    
    int main()
    {
    	// 实例化两个对象
    	Empty e1;
    	Empty e2;
    	cout << "e1 对象占用内存大小: " << sizeof(e1) << endl;
    	cout << "e2 对象占用内存大小: " << sizeof(e2) << endl;
    
    	cout << "e1 的地址: " << &e1 << endl;
    	cout << "e2 的地址: " << &e2 << endl;
    	system("pause");
    	return 0;
    }
    

    结果:

    分析

    1. 空类之所以会占用一个字节,其实这里是用来占位的
    2. 因为空类也可以实例化,如果不占用1个字节,就没办法分配内存.
    3. 当空类作为基类的时候,该类的大小就会被优化为0,这就是所谓的空白基类的最优化.

    ② 成员函数和变量分开存储

    1. 定义对象的时候会分配存储空间,但是只会为对象的成员变量分配存空间,成员函数则存放到公共的代码区.
    2. 每个对象占用的的存储空间只是该对象的数据部分,而不包括成员函数.
    3. 而成员函数存放在代码区,只有一份,那么怎么区分是哪个函数来调用的呢,通过this指针.

    三. this指针

    ① 为什么需要this指针

    1. 在建立对象的时候,对象中的数据成员会分配自己独立的存储空间.但是对于成员函数来说,一个函数的代码段在内存中只有一份.也就是说,同一个类中的不同对象在调用自己的成员函数时,其实它们调用的是同一个函数代码.
    2. 既然是调用同一个代码段,那么如何确保调用的是自己的数据成员呢? 通过this指针.其实每一个成员函数中都有一个隐藏的参数,是一个指针,名字叫this.它的值是当前被调用的成员函数所在的对象的起始地址.其实就是当前对象存放数据的起始地址.所以其对数据的引用,其实是通过this-> 这种方式去操作this指向的对象.

    ② this指针的用途

    • 用途1: 当形参和成员变量同名时,可以用this指针来区分
    /*----------------------------------------------------------------
    * 项目: Classical Question
    * 作者: Fioman
    * 邮箱: geym@hengdingzhineng.com
    * 时间: 2022/3/22
    * 格言: Talk is cheap,show me the code ^_^
    //----------------------------------------------------------------*/
    
    #include <iostream>
    using namespace std;
    class Person
    {
    public:
    	Person(string name,int age)
    	{
    		this->name = name;
    		this->age = age;
    	}
    
    private:
    	string name;
    	int age = 0;
    };
    
    int main()
    {
    	Person p("Fioman", 18);
    	system("pause");
    	return 0;
    }
    
    
    • 在类的非静态函数中返回对象本身,可使用return *this,用于链式编程.
    /*----------------------------------------------------------------
    * 项目: Classical Question
    * 作者: Fioman
    * 邮箱: geym@hengdingzhineng.com
    * 时间: 2022/3/22
    * 格言: Talk is cheap,show me the code ^_^
    //----------------------------------------------------------------*/
    
    #include <iostream>
    using namespace std;
    class Person
    {
    public:
    	Person(int money)
    	{
    		this->money = money;
    	}
    	Person &add_money(Person &p)
    	{
    		this->money += p.money;
    		return *this;
    	}
    public:
    	int money = 0;
    };
    
    int main()
    {
    	Person p1(5);
    	Person p2(100);
    	Person p3(20);
    	p1.add_money(p2); // 5 + 100 = 105
    	p1.add_money(p2).add_money(p3); // 105 + 100 + 20 = 225
    	cout << p1.money << endl;
    
    	system("pause");
    	return 0;
    }
    

    ③ this指针使用的时候注意事项

    • this指针只能在成员函数中使用
    1. 全局函数,静态函数都不能使用this指针
    2. 实际上成员函数的第一个参数为 T * const this.
    class A
    {
    public:
    	// 这个函数的原型应该是int func(A* const this,int p){}
    	int func(int p)
    	{
    		cout << "in func this 指针的地址: " << this << endl;
    	}
    };
    
    • this在成员函数开始前构造,在成员函数结束后清除
    1. 这个生命周期同任何一个函数的参数是一样的,没有任何区别.
    2. 当调用一个类的成员函数时,编译器将类的指针作为函数的this参数传递进去. 如: A a; a.func(10);
      其实编译器会翻译成A::func(&a,10);
    3. 编译器通常会对this指针做一些优化,因此,this指针的传递效率比较高.
    • this指针是什么时候创建的

    在成员函数开始执行之前构造,在成员函数执行结束后清除

    • this指针存放在何处?堆,栈,全局变量,还是其他?

    this指针会因编译器的不同而有不同的放置位置.可能是栈,也可能是期存器,甚至是全局变量.

    • this指针是如何传递类中的函数的

    大多数的编译器通过ecx寄存器传递this指针.在call之前,编译器会把对应的对象地址放到eax中.this是通过函数参数的首参来传递的.this指针在调用之前生成.类在实例化的时候,只分配类中的数据成员的空间,并没有为函数分配空间.自从类定义完成以后,它就在那里,就一份.

    • this指针是如何访问结构体中的变量的

    如果不是类,而是结构体的话,那么,如果通过结构体指针来访问结构体的变量呢?
    在C++中,类和结构体只有一个区别: 类的成员默认是private的,而结构是public.
    this是类的指针,如果换成结构体,那么this就是结构的指针了.

    • 我们只有获得一个对象后,才能通过对象this指针,如果知道了一个this指针的位置,可以直接使用吗?

    this指针只有在成员函数中有定义.所以,你获取一个对象后,也不能通过对象使用this指针.所以,我们无法知道一个对象的this指针的位置(只有在成员函数中才有this指针的位置).知道了this指针的位置之后,可以直接使用它.

    • 每个类编译后,是否创建一个类中函数表保存函数指针,以便用来调用函数?

    普通的类函数(不论是成员函数,还是静态函数)都不会创建一个函数表来保存函数指针.只有虚函数才会被放到函数表中.但是,即使是虚函数,如果编译器能明确知道用的是哪个函数,编译器就不会通过函数表中的指针来间接调用,而是会直接调用该函数.

    展开全文
  • C this指针应用简单一例,使用this指针编写程序实现对象资源的拷贝。①分配新的堆内存,②完成值的复制,调用资源复制函数。
  • this指针 通过4.3.1我们知道在C++中成员变量和成员函数是分开存储的 每一个非静态成员函数只会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码那么问题是:这—块代码是如何区分那个对象调用自己的呢? C++...

    P115 33

    在上一篇文章中,我们知道,C++中成员变量和成员函数是分开存储的
    每一个非静态成员函数只会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码那么问题是:这—块代码是如何区分那个对象调用自己的呢?

    C++通过提供特殊的对象指针,this指针,解决上述问题。this指针指向被调用的成员函数所属的对象

    this指针是隐含每一个非静态成员函数内的—种指针
    this指针不需要定义,直接使用即可

    this指针的用途:
    *·当形参和成员变量同名时,可用this指针来区分
    ·在类的非静态成员函数中返回对象本身,可使用return this

    在这里插入图片描述

    一、this指针

    1 this指针解决名称冲突

    #include <iostream>
    using namespace std;
    class Person
    {
    public:
    	Person(int age)
    	{
    		age = age;
    	}
    	int age;
    
    };
    //1 解决名称冲突
    void test1()
    {
    	Person p1(18);
    	cout << "p1的年龄为=" << p1.age << endl;
    }
    int main() 
    {
    	test1();
    	return 0;
    }
    

    输出年龄乱码
    在这里插入图片描述
    分析
    在这里插入图片描述

    光标放在形参age上,发现三个age 都是灰色,系统认为这个三个age 是同一数据

    解决1:
    将成员变量和形参书写是上加m_区分

    class Person
    {
    public:
    	Person(int age)
    	{
    		m_Age = age;
    	}
    	int m_Age;
    
    };
    

    在这里插入图片描述

    解决2:
    this指针指向 被调用的成员函数 所属对象

    class Person
    {
    public:
    	//1 解决名称冲突
    	Person(int age)
    	{
    		//this指针指向 被调用的成员函数 所属对象
    		this->age = age;
    	}
    	int age;
    
    };
    

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    2 返回对象本身用*this

    class Person
    {
    public:
    	//1 解决名称冲突
    	Person(int age)
    	{
    		//this指针指向 被调用的成员函数 所属对象
    		this->age = age;
    	}
    	
    	//2 返回对象本身用*this
    	void PersonAddAge(Person &p)
    	{
    		this->age += p.age;
    	}
    
    	int age;
    
    };
    //1 解决名称冲突
    void test1()
    {
    	Person p1(18);
    	cout << "p1的年龄为=" << p1.age << endl;
    
    	//2 返回对象本身用*this
    	Person p2(10);
    	p2.PersonAddAge(p1);
    	cout << "p2的年龄为=" << p2.age << endl;
    }
    

    在这里插入图片描述
    现在想要年龄后面继续累加,出错
    在这里插入图片描述
    函数test1()是void无返回值型,调用完毕就不能再调用了

    p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1);
    如果每次调用完毕,可以返回到p2,就可以继续再调用PersonAddAge(p1);

    //2 返回对象本身用*this
    Person &PersonAddAge(Person &p)
    {
    	//this指向p2的指针,而*this指向的就是p2这个对象的本体
    	this->age += p.age;
    	return *this;
    }
    

    完整代码

    #include <iostream>
    #include<string>
    using namespace std;
    
    //1 解决名称冲突
    
    //2 返回对象本身用*this
    
    class Person
    {
    public:
    	//1 解决名称冲突
    	Person(int age)
    	{
    		//this指针指向 被调用的成员函数 所属对象
    		this->age = age;
    	}
    	
    	//2 返回对象本身用*this
    	Person &PersonAddAge(Person &p)
    	{
    		//this指向p2的指针,而*this指向的就是p2这个对象的本体
    		this->age += p.age;
    		return *this;
    	}
    
    	int age;
    
    };
    //1 解决名称冲突
    void test1()
    {
    	Person p1(18);
    	cout << "p1的年龄为=" << p1.age << endl;
    
    	//2 返回对象本身用*this
    	Person p2(10);
    	p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1);
    	cout << "p2的年龄为=" << p2.age << endl;
    }
    
    int main() 
    {
    	test1();
    	return 0;
    }
    

    在这里插入图片描述

    二、空指针调用成员函数

    C++中空指针也是可以调用成员函数的,但是也要注意有没有用到this指针

    如果用到this指针,需要加以判断保证代码的健壮性

    #include<iostream>
    using namespace std;
    
    //空指针调用成员函数
    
    class Person
    {
    public:
    	void showClassName()
    	{
    		cout << "This is Person class" << endl;
    	}
    
    	void showPersonAge()
    	{
    		//报错原因是因为传入的是空指针
    		cout << "age=" <<m_Age<< endl;
    	}
    	int m_Age;
    };
    
    void test1()
    {
    	Person* p = NULL;
    	p->showClassName();
    //	p->showPersonAge();//报错原因是因为传入的是空指针
    }
    
    int main() 
    {
    	test1();
    	return 0;
    }
    

    在这里插入图片描述
    //报错原因是因为传入的是空指针

    if(this==NULL) return; //解决空指针出错

    void showPersonAge()
    {
    	//报错原因是因为传入的是空指针
    
    	if(this==NULL)  return; //解决空指针出错
    
    	cout << "age=" <<m_Age<< endl;
    }
    

    完整代码

    #include<iostream>
    using namespace std;
    
    //空指针调用成员函数
    
    class Person
    {
    public:
    	void showClassName()
    	{
    		cout << "This is Person class" << endl;
    	}
    
    	void showPersonAge()
    	{
    		//报错原因是因为传入的是空指针
    
    		if(this==NULL)  return; //解决空指针出错
    
    		cout << "age=" <<m_Age<< endl;
    	}
    	int m_Age;
    };
    
    void test1()
    {
    	Person* p = NULL;
    	p->showClassName();
    	p->showPersonAge();//报错原因是因为传入的是空指针
    }
    
    int main() 
    {
    	test1();
    	return 0;
    }
    

    在这里插入图片描述

    三、const修饰成员函数

    常函数:
    ·成员函数后加const后我们称为这个函数为常函数
    .常函数内不可以修改成员属性
    ·成员属性声明时加关键字mutable后,在常函数中依然可以修改

    常对象:
    ·声明对象前加const称该对象为常对象
    ·常对象只能调用常函数

    在这里插入图片描述

    在这里插入图片描述

    解决方法:
    成员属性声明时加关键字mutable,在常函数中才可以修改
    mutable int m_B;//特殊变量,即使在常函数中,也可修饰这个值,加关键字mutable

    //常函数
    class Person
    {
    public:
    	//this指针的本质是指针常量,指针的指向是不可以修改的
    	//const Person *const this;
    	//在成员函数后面加const,修饰的是this指向,让指针指向的值也不可以修改
    	void showPerson() const
    	{
    	//	m_A = 100; //常函数内不可以修改成员属性
    	//	this->m_A = 100;
    	//	this = NULL;
    		m_B = 100; //成员属性声明时加关键字mutable,在常函数中才可以修改
    	}
    
    	int m_A;
    	mutable int m_B;//特殊变量,即使在常函数中,也可修饰这个值,加关键字mutable
    };
    

    const Person p;//在对象前加const变常对象

    //常对象
    void test2()
    {
    	const Person p;//在对象前加const变常对象
    //	p.m_A = 100;//报错
    	p.m_B = 100;//m_B是特殊值,在常对象下也可以修改
    
    	//常对象只能调用常函数
    	p.showPerson();
    //	p.func();//常对象不可以调用普通成员函数,因为普通成员函数可以修改属性
    }
    

    完整代码

    #include<iostream>
    using namespace std;
    
    //常函数
    //常对象
    
    class Person
    {
    public:
    	//this指针的本质是指针常量,指针的指向是不可以修改的
    	//const Person *const this;
    	//在成员函数后面加const,修饰的是this指向,让指针指向的值也不可以修改
    	void showPerson() const
    	{
    	//	m_A = 100; //常函数内不可以修改成员属性
    	//	this->m_A = 100;
    	//	this = NULL;
    		m_B = 100; //成员属性声明时加关键字mutable,在常函数中才可以修改
    	}
    
    	void func()
    	{
    
    	}
    
    	int m_A;
    	mutable int m_B;//特殊变量,即使在常函数中,也可修饰这个值,加关键字mutable
    };
    //常函数
    void test1()
    {
    	Person p;
    	p.showPerson();
    }
    
    //常对象
    void test2()
    {
    	const Person p;//在对象前加const变常对象
    //	p.m_A = 100;//报错
    	p.m_B = 100;//m_B是特殊值,在常对象下也可以修改
    
    	//常对象只能调用常函数
    	p.showPerson();
    //	p.func();//常对象不可以调用普通成员函数,因为普通成员函数可以修改属性
    }
    int main() 
    {
    	test1();
    	return 0;
    }
    

    参考:黑马程序员
    哔哩哔哩 黑马程序员

    展开全文
  • this指针

    千次阅读 2018-08-26 22:37:06
    这是因为类的成员函数内部有一个隐藏的this指针,指向了调用该函数的对象本身。 this指针传参方式有2种:通过ecx寄存器来传,通过参数压栈来传。如果函数用的__thiscall这种调用约定来修饰,那这个函数的this指针...
  • C++ this指针详解

    千次阅读 2021-05-24 03:04:22
    C++ this指针详解this 是 C++ 中的一个关键字,也是一个 const 指针,它指向当前对象,通过它可以访问当前对象的所有成员。下面是小编为大家整理的C++ this指针详解,欢迎参考~C++ this指针详解所谓当前对象,是指...
  • this指针2.1 前言(this指针的引出)2.2 什么是this指针 1. const的使用 const的使用有以下四种情况: const int* p int const *p int* const p const int* const p 我们可以通过以下图解来理解这四种情况const...
  • C++ this指针

    万次阅读 多人点赞 2019-06-07 21:13:37
    类内的一切对于成员函数来说都是透明的),那么成员函数如何知道哪个对象的数据成员要被操作呢,原因在于每个对象都拥有一个指针:this指针,通过this指针来访问自己的地址。 注意: this指针并不是对象的一部分,...
  • 前言 一、this指针定义 二、this指针的特征 三、this指针面试题
  • this 指针

    2019-10-22 20:02:34
    C++this指针,一个对象的this指针并不是对象本身的一部分,不会影响sizeof(对象)的结果。 this作用域是在类内部,当在类的非静态成员函数中访问类的非静态成员的时候, 编译器会自动将对象本身的地址作为一个隐含...
  • 【C++】this指针原理

    2020-07-17 13:41:39
    this指针this指针概念this指针工作原理this指针的使用空指针访问成员函数常函数与常对象(const修饰的函数与对象) this指针概念 概念引出 c++的数据和操作也是分开存储,并且每一个非内联成员函数(non-inline ...
  • this指针详解

    千次阅读 2020-04-17 15:58:05
    类内的一切对于成员函数来说都是透明的),那么成员函数如何知道哪个对象的数据成员要被操作呢,原因在于每个对象都拥有一个指针:this指针,通过this指针来访问自己的地址。注:this指针并不是对象的一部分,this...
  • C++ - this指针用法

    2022-01-14 20:29:56
    this指针总结
  • this指针是类“成员函数”第一个隐藏的参数,该指针指向调用成员函数的对象(当前对象) 2. this指针的特性 (1) 只能在成员函数中使用 (2) this指针的类型:类类型* const (3) this指针没有存储在对象中,因此不会...
  • this指针PPT

    2016-01-04 10:04:17
    比较齐全的this的用法.this在不同的情况下用法的说明和一些相关的总结。
  • 默认的this指针指向规则1this指针默认指向方法调用时为其指定的对象,如:obj.fun(),fun方法体中的this指针指向obj。 代码如下:var user = { name: ‘段光伟’ };user.getName = function(){ return this.name; };...
  • 一.this 指针的理解 借鉴参考http://www.cnblogs.com/kongxy/p/4581223.html this 是 js 的关键字,代表函数运行时,自动生成的一个内部对象。只能在函数内部使用。 this 指针至于函数的执行环境有关与声明环境无关...
  • this指针的作用和用法

    千次阅读 2021-07-28 13:32:34
    由于C++中成员变量和成员函数是分开存储的,所以每一个非静态成员函数只会诞生一份函数实例,就是多个同类型的对象会共用一块代码,如果需要让一块代码调用自己,可以用到this指针,this是C++提供的特殊的对象指针,...
  • C++笔记 this指针用法

    2022-04-05 22:45:46
    一、this指针 引言: 首先,我们都知道类的成员函数可以访问类的数据(限定符只是限定于类外的一些操作,类内的一切对于成员函数来说都是透明的),那么成员函数如何知道哪个对象的数据成员要被操作呢,原因在于每个...
  • C++中this指针使用

    千次阅读 2022-03-28 16:56:31
    this指针的使用: this 是 C++ 中的一个关键字,也是一个 const 指针,它指向当前对象,通过它可以访问当前对象的所有成员。 注意: 1.this 是 const 指针,它的值是不能被修改的,一切企图修改该指针的操作,如赋值...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 593,845
精华内容 237,538
关键字:

this指针