C++学习 --- 类和对象之c++对象模型和this指针

三、c++对象模型和this指针
1、成员变量和成员函数分开存储

#include <iostream>
#include <string>
using namespace std;
​
//成员变量和成员函数分开存储
//只有非静态成员变量,属于类的对象上
class Person {
    int m_A;             //非静态成员变量,属于类的对象上
    static int m_B;      //静态成员变量,不属于类的对象上
    void func() {}       //非静态成员函数,和成员变量分开存储,,不属于类的对象上
    static void func2() {}  //静态成员函数,不属于类的对象上
};
​
int Person::m_B = 0;
​
void test01() {
    Person p;
    //空对象占用内存空间:1
    //C++编译器会给每个空对象分配一个字节空间,是为了区分空对象占用内存的位置
    //每个空对象都应该有一个独一无二的内存地址
    cout << "sizeof(p) = " << sizeof(p) << endl;
}
​
void test02() {
    //p象占用内存空间:4
    Person p;
    cout << "sizeof(p) = " << sizeof(p) << endl;
}
​
int main() {
    //test01();
    test02();
​
    system("pause");
    return 0;
}

 

2、this指针概念

 

#include <iostream>
#include <string>
using namespace std;
​
//this
//1.解决名称冲突
//2.返回对象本身
class Person {
public:
    Person(int age) {
        //age = age;    //此地的age 和属性age没有关系
        //this 指针指向的是被调用的成员函数 所属的对象
        this->age = age;
    }
​
    /*  
        如果这里是Person 的返回类型
        相当于用值的方式返回局部的对象,调用拷贝构造函数,复制了一份新的数据出来。
        第一次调用后,按照p2的本体创造了一个新的数据。
        
        若以引用的方式返回,则返回本体。
    */
    
    Person &PersonAddAge(Person &p) {
        this->age += p.age;
        //this 指向p2的指针,而*this指向的就是p2这个对象的本体
        return *this;
    }
​
    int age;
};
​
​
//1.解决名称冲突
void test01() {
    Person p1(18);
    cout << "P1的年龄:" << p1.age << endl;
}
​
//2.返回对象本身用*this
void test02() {
    Person p1(10);
    Person p2(10);
    
    //链式编程思想
    p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1);
​
    cout << "P2的年龄:" << p2.age << endl;
}
​
int main() {
    
    test01();
    test02();
​
    system("pause");
    return 0;
}

 

3、空指针访问成员函数

#include <iostream>
#include <string>
using namespace std;
​
//空指针调用成员函数
class Person {
public:
    void showClassName() {
        cout << " this is Person class " << endl;
    }
​
    void showPersonAge() {
        //此处引发了异常,属性 m_Age 前都默认加了this->m_Age;
        //指针this指向的Person是一个空指针,没有指向确切的数据
        //空的值访问属性,是不可能的
        //报错原因是访问传入的指针式NULL
        //cout << "age = " << m_Age << endl;
if (this == NULL) {
            return;
        }
        cout << "age = " << this->m_Age << endl;
    }
​
    int m_Age;
};
​
void test01() {
    Person * p = NULL;
    p->showClassName();
    p->showPersonAge();
}
​
int main() {
    test01();
    
    system("pause");
    return 0;
}

 

4、const修饰成员函数

#include <iostream>
#include <string>
using namespace std;
​
//常函数:成员函数后加const
//常对象:对象前加const
class Person {
public:
    //this指针的本质是指针常量:指针的指向式不可以修改的
    //Person * const this; 指针指向的值不可以修改
    //const Person * const this; 指针指向和指针指向的内容都不可修改
    //在成员函数后面加const本质是修饰的this
    void showPerson() const {
        //this->m_A = 100;  //常函数的原因
        //this = NULL;      //this指针本身不可以修改指针的指向的
        
        this->m_B = 100;
    }
​
    void func() {
        m_A = 100;
    }
​
    int m_A;
    mutable int m_B;        //特殊的变量,即使在常函数中也可以修改这个值
};
​
void test01() {
    Person p;
    p.showPerson();
}
​
void test02() {
    const Person p;         //在对象前加const变为常对象
    //p.m_A = 100;          //常对象不可以修改普通的成员属性
    p.m_B = 100;
​
    //常对象只能调用常函数
    p.showPerson();
    //常对象不可以调用普通成员函数,因为普通成员函数可以修改属性
    //而常对象本身不允许修改属性,两者相违背。故错误
    //p.func();
}
​
int main() {
    test01();
    
    system("pause");
    return 0;
}

 

 

posted @ 2021-08-13 18:53  yiwenzhang  阅读(49)  评论(0编辑  收藏  举报