天天看點

C++核心程式設計---4.1 類和對象-封裝【P99~P105】4 類和對象

C++核心程式設計---4.1 類和對象-封裝【P99~P105】

  • 4 類和對象
    • 4.1 類和對象-封裝
      • 4.1.1 屬性和行為作為整體
      • 4.1.2 案例-設計學生類
      • 4.1.3 封裝-通路權限
      • 4.1.4 C++中 class 和 structure 的差別
      • 4.1.5 成員屬性私有化
      • 4.1.6 設計案例1-立方體類
      • 4.1.7 設計案例2-點和圓關系
      • 4.1.7(補)類的分檔案編寫
        • 7.1.7.1 源檔案
        • 4.1.7.2 point類
          • point.h
          • point.cpp
        • 4.1.7.3 circle類
          • circle.h
          • circle.cpp

4 類和對象

C++面向對象的三大特性:封裝、繼承和多态

C++認為萬事萬物皆為對象,對象上有其屬性和行為

C++核心程式設計---4.1 類和對象-封裝【P99~P105】4 類和對象
  • 類中的屬性和行為我們統一稱為成員
  • 屬性 成員屬性 成員變量
  • 行為 成員函數 成員方法

4.1 類和對象-封裝

封裝是C++面向對象三大特性之一

封裝的意義:

  • 将屬性和行為作為一個整體,表現生活中的事物
  • 将屬性和行為加以權限控制

4.1.1 屬性和行為作為整體

C++核心程式設計---4.1 類和對象-封裝【P99~P105】4 類和對象
#include<iostream>
using namespace std;

//設計一個圓類,求圓的周長  2 * PI * 半徑
const double PI = 3.14;
//class代表設計一個類,類後面緊跟着的就是類名稱

class Circle
{
	//通路權限
public:
	//屬性
	int m_r;//半徑
	//行為:擷取圓的周長
	double calculateZC()
	{
		return 2 * PI * m_r;
	}
};

int main()
{
	//通過圓類建立一個具體的對象:圓
	//執行個體化:通過一個類建立一個對象的過程
	Circle c1;
	c1.m_r = 10;
	cout << "圓的周長為: " << c1.calculateZC() << endl;

	system("pause");
	return 0;
}
           

4.1.2 案例-設計學生類

設計一個學生類,屬性有姓名和學号,可以給姓名和學号指派,可以顯示學生的姓名和學号

#include<iostream>
using namespace std;
#include<string>

//class代表設計一個類,類後面緊跟着的就是類名稱

class Student
{
	//通路權限
public:
	//屬性
	string  m_Name;//學生姓名
	int m_Id;//學生學号
	//行為:給姓名和學号指派,顯示學生的姓名和學号
	void setName(string name)
	{
		m_Name = name;
	}

	void setId(int id)
	{
		m_Id = id;
	}

	void showStudent()
	{
		cout << "姓名: " << m_Name << "學号: " << m_Id << endl;
	}
};

int main()
{
	
	//執行個體化:建立一個具體的學生
	Student Stu1;
	//給Stu1對象進行屬性指派操作
	/*Stu1.m_Name = "張三";
	Stu1.m_Id = 01;*/
	Stu1.setName("張三");
	Stu1.setId(01);
	//顯示姓名和學号
	Stu1.showStudent();

	Student Stu2;
	//給Stu1對象進行屬性指派操作
	Stu2.m_Name = "李四";
	Stu2.m_Id = 02;
	//顯示姓名和學号
	Stu2.showStudent();

	system("pause");
	return 0;
}
           

4.1.3 封裝-通路權限

C++核心程式設計---4.1 類和對象-封裝【P99~P105】4 類和對象
  • 公共權限public: 類内類外均可以通路
  • 保護權限protected: 類内可以通路,類外不可以通路,在繼承中,兒子可以通路父親中的保護内容
  • 私有權限private: 類内可以通路,類外不可以通路,在繼承中,兒子不可以通路父親的私有内容
# include<iostream>
using namespace std;
#include<string>

class Person
{
public:
	string m_Name;//姓名
protected:
	string m_Car;//汽車
private:
	int m_Password;//銀行卡密碼

public:
	void func()//不會報錯,因為三個屬性都支援類内通路
	{
		m_Name = "張三";
		m_Car = "别克";
		m_Password = 123456;
	}
};

int main()
{
	Person p1;
	p1.m_Name = "李四";
	p1.m_Car = "奔馳";//報錯:保護權限的内容在類外無法通路
	p1.m_Password = 234567;//報錯:私有權限在類外也是無法通路

	system("pause");
	return 0;
}
           

4.1.4 C++中 class 和 structure 的差別

在C++中,struct 和 class 唯一的差別就在于 預設的通路權限不同

差別:

  • struct 預設權限為公共
  • class 預設權限為私有
# include<iostream>
using namespace std;
#include<string>

class C1
{
	int m_A;//預設權限是私有
};

struct C2
{
	int m_A;//預設權限是公共
};

int main()
{
	C1 c1;
	c1.m_A = 100;//報錯

	C2 c2;
	c2.m_A = 100;//不報錯

	system("pause");
	return 0;
}
           

4.1.5 成員屬性私有化

優點1: 将所有成員屬性設定為私有,可以自己控制讀寫權限

優點2: 對于寫權限,可以檢測資料的有效性

通常情況下,如果我們把屬性都設定為了私有,會對外為這些屬性提供一些 public 的接口來對這些屬性進行通路

# include<iostream>
using namespace std;
#include<string>

class Person
{
public:
	//寫姓名(設定姓名)
	void setName(string name)
	{
		m_Name = name;
	}
	//讀姓名(擷取姓名)
	string getName()
	{
		return m_Name;
	}
	//擷取年齡,隻讀
	int getAge()
	{
		m_Age = 0;//初始化為0歲
		return m_Age;
	}
	//設定情人,隻寫
	void setLover(string lover)
	{
		m_Lover = lover;
	}
private:
	string m_Name;//姓名	可讀可寫
	int m_Age;//年齡	隻讀
	string m_Lover;//情人	隻寫
};
int main()
{
	Person p;
	p.setName("張三");
	cout << "姓名為: " << p.getName() << endl;
	cout << "年齡為: " << p.getAge() << endl;
	p.setLover("倉井");

	system("pause");
	return 0;
}
           

4.1.6 設計案例1-立方體類

C++核心程式設計---4.1 類和對象-封裝【P99~P105】4 類和對象
  • 成員屬性:m_L、m_W、m_H
  • 成員行為:擷取立方體面積、擷取立方體體積
  • 另外,成員屬性私有化後要設定 public 權限通路接口,即設定、擷取立方體的長寬高
# include<iostream>
using namespace std;
#include<string>

//立方體類設計
//1、建立立方體類
//2、設計屬性
//3、設計行為擷取立方體面積和體積
//4、分别利用全局函數和成員函數判斷兩個立方體是否相等

class Cube
{
private:
	int m_L;
	int m_W;
	int m_H;
public:
	//通路接口:設定長
	void setL(int l)
	{
		m_L = l;
	}
	//通路接口:擷取長
	int getL()
	{
		return m_L;
	}
	//通路接口:設定寬
	void setW(int w)
	{
		m_W = w;
	}
	//通路接口:擷取寬
	int getW()
	{
		return m_W;
	}
	//通路接口:設定高
	void setH(int h)
	{
		m_H = h;
	}
	//通路接口:擷取高
	int getH()
	{
		return m_H;
	}
	//擷取立方體面積
	int calculateS()
	{
		return 2 * (m_L * m_W + m_L * m_H + m_W * m_H);
	}
	//擷取立方體體積
	int calculateV()
	{
		return m_L * m_W * m_H;
	}
	//利用成員函數判斷兩個立方體是否相等
	bool isSameByClass(Cube &c)
	{
		if (m_L == c.getL() && m_W == c.getW() && m_H == c.getH())
			return 1;
		else
			return 0;
	}
};
//利用全局函數判斷兩個立方體是否相等
bool isSame(Cube &c1, Cube &c2)
{
	if (c1.getL() == c2.getL() && c1.getW() == c2.getW() && c1.getH() == c2.getH())
		return 1;
	else
		return 0;
}

int main()
{
	//建立一個立方體的對象
	Cube c1;
	c1.setL(10);
	c1.setW(10);
	c1.setH(10);

	cout << "c1的面積為: " << c1.calculateS() << endl;
	cout << "c1的體積為: " << c1.calculateV() << endl;

	Cube c2;
	c2.setL(10);
	c2.setW(10);
	c2.setH(11);

	bool req = isSame(c1, c2);
	if (req)
	{
		cout << "c1和c2是相等的" << endl;
	}
	else
	{
		cout << "c1和c2是不相等的" << endl;
	}

	bool res = c1.isSameByClass(c2);
	if (res)
	{
		cout << "成員函數判斷:c1和c2是相等的" << endl;
	}
	else
	{
		cout << "成員函數判斷:c1和c2是不相等的" << endl;
	}

	system("pause");
	return 0;
}
           

4.1.7 設計案例2-點和圓關系

C++核心程式設計---4.1 類和對象-封裝【P99~P105】4 類和對象
C++核心程式設計---4.1 類和對象-封裝【P99~P105】4 類和對象
# include<iostream>
using namespace std;
#include<string>

class Point
{
public:
	//設定x
	void setX(int x)
	{
		m_X = x;
	}
	//擷取x
	int getX()
	{
		return m_X;
	}
	//設定y
	void setY(int y)
	{
		m_Y = y;
	}
	//擷取y
	int getY()
	{
		return m_Y;
	}

private:
	int m_X;
	int m_Y;

};

class Circle
{
public:
	//設定半徑
	void setR(int r)
	{
		m_R = r;
	}
	//擷取半徑
	int getR()
	{
		return m_R;
	}
	//設定圓心
	void setCenter(Point center)
	{
		m_Center = center;
	}
	//擷取圓心
	Point getCenter()
	{
		return m_Center;
	}

private:
	int m_R;
	Point m_Center;//圓心
};

//判斷點和圓關系
void isInCircle(Circle &c,Point &p)
{
	//計算兩點之間距離的平方
	int distance = (c.getCenter().getX() - p.getX()) * (c.getCenter().getX() - p.getX()) + 
		(c.getCenter().getY() - p.getY()) * (c.getCenter().getY() - p.getY());
	//計算半徑的平方
	int rDistance = c.getR() * c.getR();
	//判斷關系
	if (distance == rDistance)
	{
		cout << "點在圓上" << endl;
	}
	else if (distance > rDistance)
	{
		cout << "點在圓外" << endl;
	}
	else
	{
		cout << "點在圓内" << endl;
	}
		
}

int main()
{
	//建立圓
	Circle c;
	c.setR(10);
	Point center;
	center.setX(10);
	center.setY(0);
	c.setCenter(center);
	//建立點
	Point p;
	p.setX(10);
	p.setY(11);
	//比較
	isInCircle(c, p);

	system("pause");
	return 0;
}
           

4.1.7(補)類的分檔案編寫

這樣就完成了本案例,但是可以發現在做複雜一些的程式的話可能有很多類,若是都被放在一個檔案裡,簡直太長了,一般我們會将類放在其他的檔案下,讓項目結構更加清晰。

7.1.7.1 源檔案

#include<iostream>
#include<string>
#include "point.h"
#include "circle.h"

using namespace std;

//判斷點和圓關系
void isInCircle(Circle &c,Point &p)
{
	//計算兩點之間距離的平方
	int distance = (c.getCenter().getX() - p.getX()) * (c.getCenter().getX() - p.getX()) + 
		(c.getCenter().getY() - p.getY()) * (c.getCenter().getY() - p.getY());
	//計算半徑的平方
	int rDistance = c.getR() * c.getR();
	//判斷關系
	if (distance == rDistance)
	{
		cout << "點在圓上" << endl;
	}
	else if (distance > rDistance)
	{
		cout << "點在圓外" << endl;
	}
	else
	{
		cout << "點在圓内" << endl;
	}
}

int main()
{
	//建立圓
	Circle c;
	c.setR(10);
	Point center;
	center.setX(10);
	center.setY(0);
	c.setCenter(center);
	//建立點
	Point p;
	p.setX(10);
	p.setY(11);
	//比較
	isInCircle(c, p);

	system("pause");
	return 0;
}
           

4.1.7.2 point類

point.h
#pragma once
#include<iostream>
using namespace std;

class Point
{
public:
	//設定x
	void setX(int x);
	//擷取x
	int getX();
	//設定y
	void setY(int y);
	//擷取y
	int getY();

private:
	int m_X;
	int m_Y;
};
           
point.cpp
#include "point.h"

void Point::setX(int x)
{
	m_X = x;
}
//擷取x
int Point::getX()
{
	return m_X;
}
//設定y
void Point::setY(int y)
{
	m_Y = y;
}
//擷取y
int Point::getY()
{
	return m_Y;
}
           

4.1.7.3 circle類

circle.h
#pragma once
#include<iostream>
#include "point.h"
using namespace std;

class Circle
{
public:
	//設定半徑
	void setR(int r);
	//擷取半徑
	int getR();
	//設定圓心
	void setCenter(Point center);
	//擷取圓心
	Point getCenter();

private:
	int m_R;
	Point m_Center;//圓心
};
           
circle.cpp
#include "circle.h"

//設定半徑
void Circle::setR(int r)
{
	m_R = r;
}
//擷取半徑
int Circle::getR()
{
	return m_R;
}
//設定圓心
void Circle::setCenter(Point center)
{
	m_Center = center;
}
//擷取圓心
Point Circle::getCenter()
{
	return m_Center;
}
           

注意事項:

  • .h檔案中隻寫成員函數聲明,具體函數實作寫在.cpp中
  • .cpp寫函數時加上作用域并且包含對應的.h頭檔案

繼續閱讀