• 【C++编程语言】之C++对象模型和this指针


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

    ​ 在C++中,类内的成员变量和成员函数分开存储,只有非静态成员变量才存放类的对象内存

    class Person{
        
    };
    void test01(){
        //空对象占有内存空间为1
        /*C++编译器会给每个对象也分配一个字节空间,是为了区分空对象占内存中
        													的位置。*/
        //每个空对象也应该有一个独一无二的内存地址
        Person p;
        cout <<"对象占内存"<<sizeof(p)<<endl;//输出为1
    }
    
    class Struend{
        int m_A;//非静态的成员变量,存放在类的对象内存
        static int m_B;//静态的成员变量,不存放类的对象内存
        void func1(){};//非静态成员函数,不存放类的对象内存
        static void func2(){};//静态成员函数,不存放类的对象内存
    };
    void test02(){
        Struend stu;
        cout <<"对象占内存"<<sizeof(stu)<<endl;//输出为4
        //当在类中添加static int m_B;时
        cout <<"对象占内存"<<sizeof(stu)<<endl;//输出为4
        //当在类中添加 void func(){};时
        cout <<"对象占内存"<<sizeof(stu)<<endl;//输出为4   
        //当在类中添加 static void func2(){};时
        cout <<"对象占内存"<<sizeof(stu)<<endl;//输出为4   
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    2.this指针概念

    ​ C++中的成员变量和成员函数是分开存储的,每一个非静态变量成员函数只会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码。

    ​ 那么问题是:这一块代码是如何区分那个对象调用自己呢?

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

    在这里插入图片描述

    ​ 当this所属的函数被p1调用,那么this这个指针就指向p1所属对象。

    this指针的本质:是指针常量,指针常量的指向不可改变,指向的内容可以改变。

    this的用途:

    ​ 1.当形参和成员变量同名时,可以用this指针来区分

    ​ 2.在类的非静态成员函数中返回对象本身,可使用 return *this

    class Person{
       public:
        	int Age;
        	Person(int Age){
                this->Age = Age;
            }
        	void PersonAddAge(Person &p){
                this->age += p.age;
            }
        	Person& PersonAddAge2(Person &p){
                this->age += p.age;
                return *this;
            }
        	
    };
    //当形参和成员变量同名时,可以用this指针来区分
    void test01(){
        Person p1(18);
        cout << p1.Age<< endl;
    }
    //返回对象本身用*this
    void test02(){
        Person p1(12);
        Person p2(18);
        p2.PersonAddAge(p1)//输出是:30
        /*如果要实现这种
        		p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1);
       PersonAddAge()的返回值要是 Person&  *this指向的是调用该函数对象本身
        //PersonAddAge2的返回值是Person& Person的引用,所以一直是指向p2的
        p2.PersonAddAge2(p1).PersonAddAge2(p1).PersonAddAge2(p1);
        //输出是:44   这个也是链式编程
        */
        //当返回值是Person时
        p2.PersonAddAge2(p1).PersonAddAge2(p1).PersonAddAge2(p1);
        //返回值是 30
        //因为这时调用的拷贝函数创建的新对象,不是p2
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    3.空指针访问成员函数

    ​ C++中空指针也是可以调用成员函数的,但是也要注意有没有用到this指针,如果用到this指针,需要加以判断保证代码健壮性。

    class Person{
        public:
        	int m_Age;
        	void showClassName(){
                cout <<"this is Person class"<<endl;
            }
        	void showPersonAge(){
                //为了防止传来空指针,因此报错所以
                if(this == NULL){
                    return;
                }
                cout <<"age = "<<this->m_Age<<endl;
            }
    };
    void test01(){
        Person *p;
        p->showClassName();//可以调用
        
        p->showPersonAge;
        //不可以调用,this指向是一个空指针,没有对象无法访问到m_Age
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    4.const修饰成员函数

    常函数:

    ​ 1.成员函数后加const后称这个函数为常函数

    ​ 2.常函数内不可以修改成员属性

    ​ 3.成员属性声明时加关键字mutable后,在常函数中才可以修改。

    常对象:

    ​ 1.声明对象前加const称该对象为常对象

    ​ 2.常对象只能调用常函数。

    常函数

    class Person{
        public:
        	int m_A;
        	mutable int m_B;
        	void showPerson() const {
                m_A = 100;//报错,常函数内不可以修改成员变量
                //因为m_A = 100;是等价于 this->m_A = 100;
                /*this指针的本质:是指针常量,指针常量的指向不可改变,
                				指向的内容可以改变。*/
          /*当函数没有加const时,是指针常量const Person *const this;
            当在函数上加const时就变成 const Person *const this;this这个指
            针变成 常量指针常量  这样this指针的指向和内容都不可以改变。*/
                m_B = 100;//可以修改,因为m_B上面加了关键字mutable
            }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    常对象

    class Person{
        public
            int m_A;
        	mutable int m_B;
        	void showPerson() const{
                
            }
        	void func(){
                
            }
    };
    void main(){
        const Person p;//在对象前加const,变为常对象
        p.m_A = 100;//报错,因为常对象不可以修改属性
        p.m_B = 100;//可以,因为加了关键字mutable
        p.showPerson();//可以调用
        p.func();//报错,常对象不可以调用普通函数,只能调用常函数
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
  • 相关阅读:
    从零开始的Socket编程 零
    微软为金融界带来革命性突破——推出Microsoft 365中的下一代AI助手:Microsoft Copilot for Finance
    gdb调试常用概念整理
    codeblocks提示没有编译器,安装MinGW及运行heloword的方法
    shouldComponentUpdate 是做什么的?
    python中math模块
    代理IP与网络安全在跨境电商中的关键作用
    (四)、传热学-热传导问题的数值解法
    jmeter-11-Ant接口自动化及持续集成整合
    CSS盒子模型及属性
  • 原文地址:https://blog.csdn.net/kaszxc/article/details/126786820