一、类和对象
C++面向对象的三大特性为:封装、继承、多态
C++认为万事万物皆为对象,对象上有其属性和行为
**例如:**人可以作为对象,属性有姓名、年龄、身高......,行为有走、吃、睡觉
车也可以作为对象,属性有轮胎、方向盘、车灯......,行为有载人
具有相同性质的对象,我们可以抽象称为类,人属于人类,车属于车类
1.1 封装
1.1.1 封装的意义
① 将属性(成员属性、成员变量)和行为(成员函数、成员方法)作为一个整体(成员),表现生活中的事物
② 将属性和行为加以权限控制
封装意义一:
cpp
#include <iostream>
using namespace std;
#define PI 3.14
class 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;
}
封装意义二:
类在设计时,可以把属性和行为放在不同的权限下加以控制
访问权限有三种:
-
public 公共权限:成员 类内可以访问 类外可以访问
-
protected 保护权限:成员 类内可以访问 类外不可以访问 子类可以访问父类中的保护内容
-
private 私有权限:成员 类内可以访问 类外不可以访问 子类不可以访问父类中的私有内容
1.1.2 struct和class的区别
在C++中struct和class唯一的区别 就在于默认的访问权限不同
struct默认权限为公共,class默认权限为私有
1.1.3 成员属性设置为私有
优点1:将所有成员属性设置为私有,可以自己控制读写权限
优点2:对于写权限,可以检测数据的有效性
cpp
#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; 报错,不可读
}
cpp
#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;
}
案例:判断点和圆的关系(在一个类中将另一个类作为成员,将不同的类拆成不同的文件)
cpp
#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
cpp
#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
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
cpp
#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
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
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;
}