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

在C++中,类内的成员变量和成员函数分开储存

只有非静态成员变量才属于类的对象上

#include <iostream>
using namespace std;

class Person {
    public:
        int m_A; 
        static int m_B; 
        void func() {
            
        }  
};

int Person::m_B = 0;

int main() { 
    Person p;
    cout << sizeof(p) << endl; //4 
    //空对象占用的内存空间为 1
    //不是空对象,比如有一个int成员变量 内存空间变为4 
    //静态成员不属于类的对象上 不占内存空间 
    //成员函数 属于类的对象上 不占内存空间 
}

this 指针概念

我们知道了C++成员变量和成员函数是分开储存的

每一个非静态成员函数只会诞生一份函数实例,也就是说多个同类型对象会共用一块代码

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

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

this指针是隐含每一个非静态成员函数内的一种指针

this指针不需要定义,直接用即可

 

this指针的用途:

  • 当形参和成员变量同名时,可用this指针来区分
  • 在类的非静态成员函数中返回对象本身,可使用 return *this
#include <iostream>
using namespace std;

class Person {
    public:
        Person(int age) {
            this->age = age; //解决名称冲突,this指针指向被调用的成员函数所属的对象 
        }
        Person& PersinAddAge(Person &p) {
            this->age += p.age;
            return *this; //this指向p2的指针,而*this指向的就是p2这个对象本体 
        }
        
         int age;
};



int main() { 
    Person p1(10);//这里调用有参构造,this指向p1 
    cout << "p1的年龄为:" << p1.age << endl; //10
    Person p2(10);
    //链式编程思想 
    p2.PersinAddAge(p1).PersinAddAge(p1).PersinAddAge(p1);
    cout << "p2的年龄为:" << p2.age << endl; //40 如果不是引用的返回则是20 
}

空指针访问成员函数

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

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

#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; //相当于this->m_Age 
        }
        
        int m_Age;    
};

int main() { 
    Person * p = NULL;
    p->showClassName(); //不报错 
    p->showPersonAge(); //错误 
}

const修饰成员函数

常函数:

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

常对象:

  • 声明对象前加const称该对象为常对象
  • 常对象只能调用常函数
#include <iostream>
using namespace std;

class Person {
    public:
        //this指针的本质 是指针常量 指针的指向不可以修改 
        void showPerson() const{
            //const修饰的是this指针 让指针指向的值也不可以修改 
            //相当于const Person * const this 
            //this = NULL; this指针不可以修改指针的指向 
            //m_A = 100;  this->m_A报错 不可以修改指针指向的值 
            m_B = 100; // 不报错 
        }
        
        void test(){
            m_A = 100; 
        }
        
        int m_A;
        mutable int m_B; //即使在常函数中,也可以修改 
        
};

int main() { 
    Person p;
    p.showPerson(); 
    
    const Person p2{}; //常对象,不能修改指针指向的值 
    //p2.m_A = 100; 不可修改属性 
    p2.m_B = 100; 
    p2.showPerson(); //只能调用常函数 
    //p2.test();  不能调用普通成员函数 因为普通成员函数可以修改属性 
}