一、類和對象
C++面向對象的三大特性為:封裝、繼承、多態
C++認為萬事萬物皆為對象,對象上有其屬性和行為
例如:人可以作為對象,屬性有姓名、年齡、身高......,行為有走、吃、睡覺
? ? ? ? ? ?車也可以作為對象,屬性有輪胎、方向盤、車燈......,行為有載人
? ? ? ? ? ?具有相同性質的對象,我們可以抽象稱為類,人屬于人類,車屬于車類
1.1 封裝
1.1.1 封裝的意義
① 將屬性(成員屬性、成員變量)和行為(成員函數、成員方法)作為一個整體(成員),表現生活中的事物
② 將屬性和行為加以權限控制
封裝意義一:
#include <iostream>using namespace std;#define PI 3.14class Circle
{
public:int c_r;double calculate_zc(){return 2 * PI * c_r;}
};int main(int argc, char* argv[])
{Circle circle1;circle1.c_r = 10;cout << "圓的周長為:" << circle1.calculate_zc() << endl;
}
封裝意義二:
類在設計時,可以把屬性和行為放在不同的權限下加以控制
訪問權限有三種:
1. public 公共權限:成員 類內可以訪問 類外可以訪問? ? ? ??
2. protected 保護權限:成員 類內可以訪問 類外不可以訪問 子類可以訪問父類中的保護內容? ? ? ??
?3. private 私有權限:成員 類內可以訪問 類外不可以訪問 子類不可以訪問父類中的私有內容
1.1.2 struct和class的區別
在C++中struct和class唯一的區別就在于默認的訪問權限不同
struct默認權限為公共,class默認權限為私有
1.1.3?成員屬性設置為私有
優點1:將所有成員屬性設置為私有,可以自己控制讀寫權限
優點2:對于寫權限,可以檢測數據的有效性
#include <iostream>
#include <string>using namespace std;class Student
{
private:string stu_Name; // 可讀可寫string stu_Num = "23S101111"; // 只讀int stu_Age; // 只寫public:void setName(string name) {stu_Name = name; // 可寫}string getName(){return stu_Name; // 可讀}string getNum(){return stu_Num; // 只讀}void setAge(int age){if (age < 0 || age>150) // 檢測數據有效性{cout << "年齡輸入有誤,已重置為0" << endl;stu_Age = 0;return;}stu_Age = age; // 只寫}
};int main(int argc, char* argv[])
{Student stu;stu.setName("張三");cout << stu.getName() << endl;// stu.stu_Num = "23S101111"; 報錯,不可寫cout << stu.getNum() << endl; stu.setAge(150);stu.setAge(151);// cout << stu.stu_Age << endl; 報錯,不可讀
}
#include <iostream>using namespace std;// 立方體類設計
// 1. 創建立方體類
// 2. 設計立方體屬性 獲取立方體的長寬高
// 3. 設計立方體行為 獲取立方體面積和體積
// 4. 分別利用全局函數和成員函數 判斷兩個立方體是否相等class Cube
{
private:double cube_L, cube_W, cube_H;public:void setL(double length){cube_L = length;}double getL(){return cube_L;}void setW(double width){cube_W = width;}double getW(){return cube_W;}void setH(double height){cube_H = height;}double getH(){return cube_H;}double calculate_S(){return 2 * (cube_L * cube_W + cube_L * cube_H + cube_W * cube_H);}double calculate_V(){return cube_L * cube_W * cube_H;}bool isSameByClass(Cube &cube){if (cube_L == cube.getL() && cube_W == cube.getW() && cube_H == cube.getH()){return true;}return false;}
};bool isSame(Cube &cube_one, Cube &cube_two)
{if (cube_one.getL() == cube_two.getL() && cube_one.getW() == cube_two.getW() && cube_one.getH() == cube_two.getH()){return true;}return false;
}int main(int argc, char* argv[])
{Cube cube_one;cube_one.setL(10);cube_one.setW(10);cube_one.setH(10);cout << "該立方體的表面積為:" << cube_one.calculate_S() << endl;cout << "該立方體的體積為:" << cube_one.calculate_V() << endl;Cube cube_two;cube_two.setL(10);cube_two.setW(10);cube_two.setH(11);cout << "該立方體的表面積為:" << cube_two.calculate_S() << endl;cout << "該立方體的體積為:" << cube_two.calculate_V() << endl;bool issame = isSame(cube_one, cube_two);issame == 1 ? cout << "全局函數判斷兩個立方體相同" : cout << "全局函數判斷兩個立方體不相同";cout << endl;bool issameByClass = cube_one.isSameByClass(cube_two);issameByClass == 1 ? cout << "成員函數判斷兩個立方體相同" : cout << "成員函數判斷兩個立方體不相同";cout << endl;
}
案例:判斷點和圓的關系(在一個類中將另一個類作為成員,將不同的類拆成不同的文件)
#include <iostream>
#include <cmath>using namespace std;class Point
{
private:double point_X;double point_Y;
public:void set_X(double x){point_X = x;}double get_X(){return point_X;}void set_Y(double y){point_Y = y;}double get_Y(){return point_Y;}
};class Circle
{
private:Point circleCenter;double circleR;
public:void setR(double r){circleR = r;}double getR(){return circleR;}void setCircleCentre(Point p){circleCenter = p;}Point getCircleCentre(){return circleCenter;}
};void isInCircle(Circle c, Point p)
{double distance;distance = sqrt(pow(c.getCircleCentre().get_X() - p.get_X(), 2) + pow(c.getCircleCentre().get_Y() - p.get_Y(), 2));if (distance == c.getR()){cout << "點在圓上" << endl;}else if (distance < c.getR()){cout << "點在圓內" << endl;}else{cout << "點在圓外" << endl;}
}int main(int argc, char* argv[])
{Point p;p.set_X(10);p.set_Y(11);Point centre;centre.set_X(10);centre.set_Y(0);Circle circle;circle.setCircleCentre(centre);circle.setR(10);isInCircle(circle, p);return 0;
}
如何把不同的類寫入不同的文件
在頭文件中創建一個point.h,源文件中創建一個point.cpp
point.h
#pragma once
#include <iostream>using namespace std;class Point
{
private:double point_X;double point_Y;
public:void set_X(double x);double get_X();void set_Y(double y);double get_Y();};
point.cpp
#include "point.h"void Point::set_X(double x)
{point_X = x;
}
double Point::get_X()
{return point_X;
}
void Point::set_Y(double y)
{point_Y = y;
}
double Point::get_Y()
{return point_Y;
}
在頭文件中創建一個circle.h,源文件中創建一個circle.cpp
circle.h
#pragma once
#include <iostream>
#include "point.h"using namespace std;class Circle
{
private:Point circleCenter;double circleR;
public:void setR(double r);double getR();void setCircleCentre(Point p);Point getCircleCentre();
};
circle.cpp
#include "circle.h"void Circle::setR(double r)
{circleR = r;
}
double Circle::getR()
{return circleR;
}
void Circle::setCircleCentre(Point p)
{circleCenter = p;
}
Point Circle::getCircleCentre()
{return circleCenter;
}
main.cpp
#include <iostream>
#include <cmath>
#include "circle.h"
#include "point.h"using namespace std;void isInCircle(Circle c, Point p)
{double distance;distance = sqrt(pow(c.getCircleCentre().get_X() - p.get_X(), 2) + pow(c.getCircleCentre().get_Y() - p.get_Y(), 2));if (distance == c.getR()){cout << "點在圓上" << endl;}else if (distance < c.getR()){cout << "點在圓內" << endl;}else{cout << "點在圓外" << endl;}
}int main(int argc, char* argv[])
{Point p;p.set_X(10);p.set_Y(9);Point centre;centre.set_X(10);centre.set_Y(0);Circle circle;circle.setCircleCentre(centre);circle.setR(10);isInCircle(circle, p);return 0;
}