title: c++學習筆記之封裝篇(上)
date: 2017-03-12 18:59:01
tags: [c++,c,封裝,類]
categories: [學習,程式員,c/c++]
---
一、類對象
假設我們由Tv這個類,定義如下
注意class結尾要加上分号
class Tv()
{
int width;
int height;
int volume;
void changeVolume()
{
//changeVolume
}
};
類的執行個體化有兩種方法,一種是棧中執行個體化。另一種則是堆中執行個體化。
而這兩種方法除了在用法上有差別以外(差別見下面代碼),記憶體管理也有差別(棧不用考慮記憶體回收問題,系統會自動回收,而堆則需要程式員主動釋放記憶體)。
1.執行個體化
- 從棧中執行個體化對象
Tv tv;
或者
Tv tv[20] //執行個體化對象數組 從棧中執行個體化系統自動回收記憶體
- 從堆中執行個體化對象
執行個體化一個對象後還需要判斷是否成功申請到記憶體
Tv *p = new Tv();
Tv *q = new Tv[20]; //開辟一塊對象記憶體
if(p==NULL)
{
cout<<"類執行個體化失敗"<<endl;
}
//從堆中執行個體化數組對象,需要程式員回收
delete p;
delete[]q;
p = NULL;
q =NULL;
通路資料
- 通過棧執行個體化的對象通路資料成員:
tv.volume = 5;
tv.changeVolume();
- 通過堆執行個體化的對象通路資料成員:
tv->volume = 5;
tv->changeVolume();
二、string
可以很友善的定義一個字元串,而不再是使用麻煩的char[].
使用方法:
// 引入string頭檔案
#include <string>
初始化方法
注意:第4個初始化方法中的第二個參數隻能是一個字元,不能是字元串。
常用操作
對于字元串相加操作,需要注意一點,不能直接使用兩個字元串相加,中間必須得有字元串變量連接配接才行(下面例子中最後一個指派語句是錯誤的),具體例子如下:
另外如果要将字元串和整數連在一起輸出,則需要在整數前加上 << 進行處理,直接用 “+” 是無效的。
string name;
cin>>name;
cout<<name<<name.size()<<endl;
三、構造函數
- 構造函數必須與類同名,起到的作用與python中的 **_ init > _()** 函數類似,即對類進行資料初始化。
- 構造函數在對象執行個體化時被自動調用,且隻調用一次。
- 構造函數沒有傳回值,不需要return值。
- 構造函數可以重載。
1. 構造函數分為有參與無參
舉個栗子:
class Student
{
// 無參構造函數
Student()
{
m_iHeight = 180;
m_iWeight = 70;
}
// 有參構造函數
Student(int weight, int height)
{
m_iWeight = weight;
m_iHeight = height;
}
private:
int m_iWeight;
int m_iHeight;
}
2. 構造函數初始化清單
在初始化對象時,初始化清單是最先執行的,是以有的時候對于const變量我們也可以提前指派。
文法:
類名():變量1(參數),變量2(參數){}
用法:
我們都知道一個人的身份證資訊一般來說是不能随意篡改的,是以我們會使用const 來修飾,但是因為const修飾後,變量則不能再指派,但是因為每個人的身份證又不一樣,我們不可能在使用const修飾的同時進行指派,那怎麼辦呢?是以這裡用到了初始化清單來達到這麼一個效果,詳見下面的代碼示例:
class Student
{
// 正确示例
// 初始化清單
Student(string id):m_iId(id)
{
// 初始化成功
}
// 編譯會報錯
// Student(string id)
// {
// m_iId = id;
// }
private:
const string m_iId;
}
初始化類數組
Coordinate *coorArr = new Coordinate[2]{{1,2},{3,4}};
具體示例
#include <iostream>
using namespace std;
class Coordinate
{
public:
Coordinate(int x,int y):m_iX(x),m_iY(y)
{
cout<<m_iX<<","<<m_iY<<endl;
}
// 列印坐标的函數
void printInfo()
{
cout<<m_iX<<","<<m_iY<<endl;
}
private:
int m_iX;
int m_iY;
};
int main(void)
{
//定義對象數組
Coordinate *coorArr = new Coordinate[2]{{1,2},{3,4}};
//周遊數組,列印對象資訊
for(int i = 0; i < 2; i++)
{
coorArr[i].printInfo();
}
return 0;
}
3. 拷貝構造函數
-
不能重載
格式:
類名(const 類名& 變量名)
關于拷貝構造函數更具體的解析參考:
C++拷貝構造函數詳解4.析構函數
與構造函數相反,當一個對象的生命周期結束時,C++會自動調用一個特殊的成員函數,即析構函數進行善後工作,對成員變量所占記憶體進行釋放操作。
格式:(不需要參數)
~類名(){}
class Student
{
// 構造函數,初始化清單
Student():m_iId(110){};
// 析構函數,c++可以自動生成
~Student(){};
}
對象的生命曆程:
申請記憶體-->初始化清單-->構造函數-->參與運算-->析構函數-->釋放記憶體