C++面向对象的三大特性:封装、继承、多态
1.封装
- 将属性和行为作为一个整体,表现生活中的事物
const double PI = 3.14;
// 设计一个圆类,求圆的周长
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;
}
class Student
{
public:
// 属性和行为统一称为 成员
// 属性(成员属性,成员变量)
string m_name;
int m_id;
// 行为(成员函数,成员方法)
void showStudent()
{
cout << "姓名:" << m_name << " 学号:" << m_id << endl;
}
// 也可以直接赋值
void Setname(string name)
{
m_name = name;
}
void Setid(int id)
{
m_id = id;
}
};
int main()
{
Student stu;
stu.Setname("Cycal");
stu.Setid(1);
stu.showStudent();
system("pause");
return 0;
}
- 类在设计时,可以把属性和行为放在不同的权限下,加以控制
- 访问权限有三种:
- public 公共权限 :类内可以访问,类外可以访问
- protected 保护权限 :类内可以访问,类外不可以访问(子类可以访问父类的保护内容)
- private 私有权限:类内可以访问,类外不可以访问(子类不可以访问父类的私有内容)
class Person
{
public:
string m_name;
protected:
string m_car;
private:
int m_password;
public:
void fun()
{
m_name = "张三";
m_car = "拖拉机";
m_password = 123;
}
};
int main()
{
Person p1;
p1.m_name = "类似";
p1.m_car = "奔驰"; // 错误,保护权限的内容,不能在类外访问
p1.m_password = 1234; // 错误,私有权限的内容,不能在类外访问
system("pause");
return 0;
}
2.struct和class区别
在C++中,struct和class唯一的区别在于 默认的访问权限不同
- struct 默认权限为公共
- class 默认权限为私有
class C1
{
int m_A; // 默认权限是私有
};
struct C2
{
int m_A; // 默认权限是公共
};
int main()
{
C1 c1;
c1.m_A = 100; // 错误,在class里默认权限为私有,因此不能访问
C2 c2;
c2.m_A = 100; // 正确,在struct里默认权限为公共,可以访问
system("pause");
return 0;
}
3.将成员属性设置为私有
- 可以自己控制读写权限
- 对于写权限,我们可以检测数据的有效性
class Person
{
public:
// 设置姓名
void setName(string name)
{
m_name = name;
}
// 读取姓名
string getName()
{
return m_name;
}
// 读取年龄
int getage()
{
return m_age;
}
// 设置偶像
void setidol(string idol)
{
m_idol = idol;
}
// 设置年龄0-150
void setage(int age)
{
if(age < 0 || age > 150)
{
cout << "年龄有误" << endl;
return;
}
}
private:
string m_name; // 可读可写
int m_age = 18; // 只读,也可以写,但年龄必须在0-150
string m_idol; // 只写,外界访问不到
};
int main()
{
Person p;
p.setName("张三");
cout << p.getName() << endl;
cout << p.getage() << endl;
p.setidol("李四");
p.setage(160);
system("pause");
return 0;
}
4.练习案例:设计立方体类
设计立方体类Cube,求出立方体的面积和体积,分别用全局函数和成员函数判断两个立方体是否相等。
class Cube
{
public:
// 设置长宽高
void set(int L, int H, int W)
{
m_L = L;
m_H = H;
m_W = W;
}
// 读取长宽高
int load_L()
{
return m_L;
}
int load_H()
{
return m_H;
}
int load_W()
{
return m_W;
}
int mianji()
{
return 2*m_L*m_H + 2*m_H*m_W+2*m_L*m_W;
}
int tiji()
{
return m_L * m_H * m_W;
}
// 利用成员函数判断是否相等
bool same(Cube &c)
{
if (m_L == c.load_L()
&& m_H == c.load_H()
&& m_W == c.load_W())
{
return true;
}
else{
return false;
}
}
private:
int m_L;
int m_H;
int m_W;
};
// 利用全局函数判断是否相等
bool isSame(Cube &c1, Cube &c2)
{
if(c1.load_L() == c2.load_L()
&& c1.load_H() == c2.load_H()
&& c1.load_W() == c2.load_W())
{
return true;
}
else{
return false;
}
}
int main()
{
Cube c1;
c1.set(10,10,10);
cout << c1.mianji() << endl;
cout << c1.tiji() << endl;
Cube c2;
c2.set(10,10,10);
bool ret = isSame(c1, c2);
if(ret)
{
cout << "全局函数判断相等" << endl;
}
else{
cout << "全局函数判断不等" << endl;
}
bool ret2 = c1.same(c2);
if(ret2)
{
cout << "成员函数判断相等" << endl;
}
else{
cout << "成员函数判断不等" << endl;
}
system("pause");
return 0;
}
5.练习案例:点和圆的位置关系判断
主函数:
#include <iostream>
#include <string>
using namespace std;
#include "circle.h"
#include "point.h"
void isInCircle(Circle& c, Point p)
{
int distance =
(c.load_center().load_X() - p.load_X()) * (c.load_center().load_X() - p.load_X())
+ (c.load_center().load_Y() - p.load_Y()) * (c.load_center().load_Y() - p.load_Y());
int rDistance = c.load_R() * c.load_R();
if (distance == rDistance)
{
cout << "点在圆上" << endl;
}
else if (distance > rDistance)
{
cout << "点在圆外" << endl;
}
else
{
cout << "点在园内" << endl;
}
}
int main()
{
Circle c;
c.set_R(10);
Point center;
center.setX(10);
center.setY(0);
c.setCenter(center);
Point p;
p.setX(10);
p.setY(15);
isInCircle(c, p);
system("pause");
return 0;
}
circle.h 只写函数声明和属性声明
#pragma once
#include <iostream>
#include "point.h"
using namespace std;
class Circle
{
public:
void set_R(int r);
int load_R();
void setCenter(Point center);
Point load_center();
private:
int m_R;
Point m_Center;
};
circle.cpp 写函数具体实现
#include "circle.h"
void Circle::set_R(int r)
{
m_R = r;
}
int Circle::load_R()
{
return m_R;
}
void Circle::setCenter(Point center)
{
m_Center = center;
}
Point Circle::load_center()
{
return m_Center;
}
point.h
#pragma once
#include <iostream>
using namespace std;
class Point
{
public:
void setX(int x);
void setY(int y);
int load_X();
int load_Y();
private:
int m_X;
int m_Y;
};
point.cpp
#include "point.h"
void Point::setX(int x)
{
m_X = x;
}
void Point::setY(int y)
{
m_Y = y;
}
int Point::load_X()
{
return m_X;
}
int Point::load_Y()
{
return m_Y;
}
写在一个文件里
#include <iostream>
#include <string>
using namespace std;
class Point
{
public:
void setX(int x)
{
pointx = x;
}
void setY(int Y)
{
pointy = Y;
}
int getX()
{
return pointx;
}
int getY()
{
return pointy;
}
private:
int pointx;
int pointy;
};
class Circle
{
public:
void setR(int r)
{
radius = r;
}
int getR()
{
return radius;
}
void setCenter(Point point)
{
center = point;
}
Point getCenter()
{
return center;
}
private:
int radius;
Point center;
};
void Isincircle(Circle &c, Point p)
{
int distance = (p.getX()-c.getCenter().getX()) * (p.getX()-c.getCenter().getX())
+ (p.getY()-c.getCenter().getY()) * (p.getY()-c.getCenter().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(10);
Isincircle(c, p);
system("pause");
return 0;
}
与vs2022不同,使用vscode时,需要配置Cpp自定义的头文件,具体做法可以参考:适合初学者!超详细的vscode的C++自定义头文件的配置!_vscode中c++无法正确导入自定义头文件-CSDN博客