1. 程式人生 > 其它 >C++物件模型和this指標

C++物件模型和this指標

成員變數和成員函式分開儲存

在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();  不能呼叫普通成員函式 因為普通成員函式可以修改屬性 
}