面向過程和面向對象
C語言是面向過程的,關注的是過程,分析出求解問題的步驟,通過函數調用來逐步解決問題
C+++是基于面向對象的,關注的是對象,將一件事情分成不同的對象,靠對象之間完成交互
類的引入
C語言結構體中只能定義變量,在C++中,結構體不僅僅可以定義變量,而且可以定義函數,
例如 :之前用C語言實現的棧,結構體中只能定義變量,現在已C++的方式實現,不僅可以定義變量,而且還可以在結構體定義函數
?對于結構體的定義,在C++中 更喜歡用class來定義
class className
{//類體:由成員函數和成員變量來組成
};//后面一定要寫分號
?class為定義類的關鍵字,className為類的名字,{}中為類的主體,注意類定義結束之后后面的分號不能省略
類體中內容稱為類的成員:類的變量稱為類的屬性或成員變量;類中的函數被稱為類的方法或者是類的成員函數
類的兩種第一方式
1.聲明和定義全部放在類體中,需要主義:成員函數如果在類中定義,編譯器可能會把函數當作內聯函數來做處理
2.類聲明放在.h文件中,成員函數定義在.cpp的文件中,
如果這樣的話,要在函數前加上類名
C++里類域中的成員變量通常書寫前加一個_區分,可以寫在前面例如:_year,或者year_
例如:我們的成員變量如果使用的year不進行區分
傳入的變量year = year month = month day = day,通常會報錯
因為編譯器無法區分變量是函數形參還是成員變量
class Date
{
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}private:int _year; // year_ m_yearint _month;int _day;
};int main()
{Date d;d.Init(2024, 3, 31);return 0;
}
?類的訪問限定符及封裝
訪問限定符
c++實現封裝的方式:用類將對象的屬性與方法結合到一塊,讓對象更加完善,通過訪問權限選擇將其接口提供給外部的用戶使用
1. public修飾的成員在類外可以直接被訪問
2. protected和private修飾的成員在類外不能直接被訪問(此處protected和private是類似的)
3. 訪問權限作用域從該訪問限定符出現的位置開始直到下一個訪問限定符出現時為止
4. 如果后面沒有訪問限定符,作用域就到 } 即類結束。
5. class的默認訪問權限為private,struct為public(因為struct要兼容C)?注意:訪問限定符只在編譯時有用,當數據映射到內存后,沒有任何訪問限定符上的區別
封裝
面向對象的三大特性?
封裝 繼承 多態
在類和對象階段,主要是研究類的封裝性,什么事封裝?
封裝:將數據和操作數據的方法進行有機結合,隱藏對象的屬性和實現細節,僅對外公開接口來進行和對象進行交互.
封裝的本質是一種管理,讓用戶更方便使用類
在C++中實現封裝,可以通過類將數據以及操作數據的方法進行有機結合,通過訪問權限來隱藏對象內部實現細節,控制哪些方法可以在類外部直接被使用.
類的作用域
類定義了一個新的作用域,類的所有成員都在類的作用域中.在類體外定義成員時,需要使用::作用域操作符指明成員屬于哪個類域
class Person
{
public:void PrintPersonInfo();
private:char _name[20];char _gender[3];int _age;
};
// 這里需要指定PrintPersonInfo是屬于Person這個類域
void Person::PrintPersonInfo()
{cout << _name << " "<< _gender << " " << _age << endl;
}
類的實例化
用類類型創建對象的過程,稱為類的實例化
1.類是對對象進行描述的,是一個模型一樣的東西,限定了類有哪些成員,定義出一個類并沒有分配實際的內存空間來存儲他.
2.一個類可以實例化出多個對象,實例化出的對象,占用實際的物理空間,存儲類成員變量
class Person
{
public:void PrintPersonInfo();
private:char _name[20];char _gender[3];int _age;
};
int main()
{Person._age = 100;
// 編譯失敗:error C2059: 語法錯誤:“.”
//并且成員變量都是私有的不能直接使用return 0;
}
Person類是沒有空間的,只有Person類實例化的對象才有具體的空間
打個比方,類實例化出對象就像現實中使用建筑設計圖建造出房子,類就像是設計圖,只設計出需要什么東西,但沒有實體存在,同樣類也是一個設計,實例化出的對象才能實際存儲數據,占用物理空間
類對象模型
如何計算類對象的大小
class A
{
public:void PrintA(){cout<<_a<<endl;}
private:char _a;
};
類中既可以有成員變量,又可以有成員函數,那么一個類的對象中包含了什么?如何計算一個類的大小
類對象的存儲方式猜測
對象中包含類的各個成員
// 類中既有成員變量,又有成員函數
class A1 {
public:void f1(){}
private:int _a;
};
// 類中僅有成員函數
class A2 {
public:void f2() {}
};
// 類中什么都沒有---空類
class A3
{};
this指針
我們先來定義一個日期類
class Date
{
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}//void Print(Date* this)void Print(){cout << _year << "-" << _month << "-" << _day << endl;}
private:int _year; // 年int _month; // 月int _day; // 日int a;
};
int main()
{Date d1, d2;d1.Init(2022, 1, 11);d2.Init(2022, 1, 12);d1.Print();d2.Print();return 0;
}
class Date
{
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}//void Print(Date* const this)void Print(){//cout <<this-> _year << "-" << this->_month << "-" <<this-> _day << endl;cout << _year << "-" << _month << "-" << _day << endl;}
private:int _year; // 年int _month; // 月int _day; // 日int a;
};
int main()
{Date d1, d2;d1.Init(2022, 1, 11);d2.Init(2022, 1, 12);//d1.Print(&d1);d1.Print();//d2.Print(&d2);d2.Print();return 0;
}

this指針存在哪里?
this指針可以為空嗎?
傳遞空指針不會報編譯錯誤,沒有訪問,所以正常運行
class A
{
public:void Print(){cout << "Print()" << endl;}
private:int _a;
};
int main()
{A* p = nullptr;p->Print();return 0;
}
?// 1.下面程序編譯運行結果是? A、編譯報錯 B、運行崩潰 C、正常運行
運行崩潰
class A
{
public:void PrintA(){cout << _a << endl;//cout << this->_a << endl;}
private:int _a;
};
int main()
{A* p = nullptr;//p->PrintA(&p);p->PrintA();return 0;
}
this
?通常不占用對象內存,而是作為隱藏參數傳遞,可能存棧上。
有些存在ecx寄存器上

?把C語言中的結構體用C++重新實現一下
#include <iostream>
#include <stdlib.h>
#include <stdbool.h>
using namespace std;typedef int DataType;
class Stack
{
public:void Init(int n = 4){_arry = (DataType*)malloc(sizeof(DataType)*n);if (_arry == NULL){perror("malloc is fail");return;}_size = 0;_capacity = n;}int size(){return _size;}bool empty(){return _size == 0;}void push(DataType data){Checkcapacity();_arry[_size] = data;_size++;}void Pop(){if (empty()){return;}_size--;}int top(){return _arry[_size - 1];}void Destory(){free(_arry);_arry = nullptr;_capacity = 0;_size = 0;}
private:void Checkcapacity(){if (_size == _capacity){int newcapacity = _capacity * 2;DataType* temp = (DataType*)realloc(_arry, newcapacity * sizeof(DataType));if (temp == NULL){perror("realloc fail");return;}_arry = temp;_capacity = newcapacity;}}
private:DataType* _arry;int _size;int _capacity;
};int main()
{Stack st;st.Init();st.push(1);st.push(2);st.push(3);st.push(4);st.push(5);while (!st.empty()){ cout << st.top() << " ";st.Pop();}return 0;
}