1.類的定義
1.1類的定義格式
? class為定義類的關鍵字,后跟一個類的名字,{}中為類的主體,注意類定義結束時后?分號不能省 略。類體中內容稱為類的成員:類中的變量稱為類的屬性或成員變量;類中的函數稱為類的?法或 者成員函數。
? 為了區分成員變量,?般習慣上成員變量會加?個特殊標識,如成員變量前?或者后?加_或者m 開頭,注意C++中這個并不是強制的,只是?些慣例,具體看公司的要求。
?? C++中struct也可以定義類,C++兼容C中struct的?法,同時struct升級成了類,明顯的變化是 struct中可以定義函數,?般情況下我們還是推薦?class定義類。
? 定義在類?的成員函數默認為inline。
通俗點來說說呢,類就是struct的升級plus版本,將成員由c語言中struct只能夠是變量增添了函數,下面我們寫一個簡單的日期類
class Date
{
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}
private:// 為了區分成員變量,?般習慣上成員變量 // 會加?個特殊標識,如_ 或者 m開頭 int _year; // year_ m_yearint _month;int _day;
};
int main()
{Date d;d.Init(2024, 3, 31);return 0;
}
可以看出相較于c語言中的struct,類可以以函數作為成員
1.2訪問限定符
我們在上述代碼中,我們看到了其中有public和private,其中是什么意思呢?
? C++?種實現封裝的?式,?類將對象的屬性與?法結合在?塊,讓對象更加完善,通過訪問權限 選擇性的將其接?提供給外部的用戶使?。
? public修飾的成員在類外可以直接被訪問;protected和private修飾的成員在類外不能直接被訪 問,protected和private是?樣的,以后繼承章節才能體現出他們的區別。
?? 訪問權限作?域從該訪問限定符出現的位置開始直到下?個訪問限定符出現時為?,如果后?沒有 訪問限定符,作?域就到}即類結束。
? class定義成員沒有被訪問限定符修飾時默認為private,struct默認為public。
? ?般成員變量都會被限制為private/protected,需要給別?使?的成員函數會放為public
?
?在如圖所示我們就可以看到在main函數中,_year并不能被識別,這就是因為_year是被private修飾的
1.3類域
?? 類定義了?個新的作?域,類的所有成員都在類的作?域中,在類體外定義成員時,需要使?::作 ?域操作符指明成員屬于哪個類域。
? 類域影響的是編譯的查找規則,下?程序中Init如果不指定類域Stack,那么編譯器就把Init當成全 局函數,那么編譯時,找不到array等成員的聲明/定義在哪?,就會報錯。指定類域Stack,就是知 道Init是成員函數,當前域找不到的array等成員,就會到類域中去查找。
?
#include<iostream>
using namespace std;
class Stack
{
public:// 成員函數 void Init(int n = 4);
private:// 成員變量 int* array;size_t capacity;size_t top;
};
// 聲明和定義分離,需要指定類域
void Stack::Init(int n)
{array = (int*)malloc(sizeof(int) * n);if (nullptr == array){perror("malloc申請空間失敗");return;}capacity = n;top = 0;
}
int main()
{Stack st;st.Init();return 0;
}
2.this指針
? Date類中有Init與Print兩個成員函數,函數體中沒有關于不同對象的區分,那當d1調?Init和 Print函數時,該函數是如何知道應該訪問的是d1對象還是d2對象呢?那么這?就要看到C++給了 ?個隱含的this指針解決這?的問題
我們看看下列代碼?
#include<iostream>
using namespace std;
class Date
{
public:// void Init(Date* const this, int year, int month, int day)void Init(int year, int month, int day){// 編譯報錯:error C2106: “=”: 左操作數必須為左值 // this = nullptr;// this->_year = year;_year = year;this->_month = month;this->_day = day;}void Print()
{cout << _year << "/" << _month << "/" << _day << endl;}
private:// 這?只是聲明,沒有開空間 int _year;int _month;int _day;
};
int main()
{// Date類實例化出對象d1和d2 Date d1;Date d2;// d1.Init(&d1, 2024, 3, 31);d1.Init(2024, 3, 31);d1.Print();d2.Init(2024, 7, 5);d2.Print();return 0;
}
我們可以看到d1和d2都是同樣的參數,那么類是怎么區分d1和d2的呢,這就因為其中存在一個隱形指針this
?如Date類的Init的真實原型為
void Init(Date* const this, int year, int month, int day)
C++規定不能在實參和形參的位置顯?的寫this指針(編譯時編譯器會處理),但是可以在函數體內顯 ?使?this指針。
能夠準精確的分辨d1和d2就是因為有this指針
2.1this指針示例?
讓我們看看下列題目
1.下?程序編譯運?結果是()
?A、編譯報錯?B、運?崩潰?C、正常運?
#include<iostream>
using namespace std;
class A
{
public:void Print(){cout << "A::Print()" << endl;}
private:int _a;
};
int main()
{A* p = nullptr;p->Print();return 0;
}
答案是C正常運行
在看看下面這題
#include<iostream>
using namespace std;
class A
{
public:void Print(){cout << "A::Print()" << endl;cout << _a << endl;}
private:int _a;
};
int main()
{A* p = nullptr;p->Print();return 0;
}
答案是B運行錯誤,這是為什么呢?
原因就在于
下面的代碼比上面的代碼多了一行
cout << _a << endl
其中涉及了成員_a,所以這里進行訪問時對空指針進行了解引用,因此報錯。
本次的分享就到這里結束,后續會繼續分享,感謝閱讀!