关注泷羽Sec-静安 公众号,后台回复 找书+ C++Primer 获取C++相关电子书
- 类:类是一个抽象的模板,用于定义对象的属性和行为。
- 对象:对象是类的具体实例,通过类创建。
面向对象三大特性:
- 封装 (Encapsulation):通过将数据成员设为私有(private),并提供公共(public)方法来控制对数据的访问,保护数据不被外部直接修改。
- 继承 (Inheritance):通过继承基类的属性和方法,派生类可以复用基类的代码,并可以添加新的属性和方法。
- 多态 (Polymorphism):通过基类指针或引用调用派生类的重写方法,实现同一接口的不同实现。
#include <iostream>
#include <string>
using namespace std;
/*----------- 类和对象基础 -----------*/
// 类:抽象模板 | 对象:具体实例
class Dog { // 类声明
public:
string name; // 属性
void bark() { // 方法
cout << name << ": Wang Wang!" << endl;
}
};
// 使用示例:
int main() {
Dog myDog; // 创建对象
myDog.name = "Buddy";
myDog.bark(); // 输出:Buddy: Wang Wang!
/*----------- 封装 (Encapsulation) -----------*/
class BankAccount {
private: // 封装敏感数据
double balance;
public:
// 公开接口控制访问
void deposit(double amount) {
if (amount > 0) balance += amount;
}
bool withdraw(double amount) {
if (amount <= balance) {
balance -= amount;
return true;
}
return false;
}
double getBalance() { return balance; } // 只读访问
};
// 使用示例:
BankAccount acc;
acc.deposit(1000); // 合法操作
// acc.balance = 10000; // 错误:无法直接访问private成员
/*----------- 继承 (Inheritance) -----------*/
// 基类
class Vehicle {
public:
string brand;
void honk() {
cout << "Tu~ Tu~" << endl;
}
};
// 派生类
class Car : public Vehicle { // 继承语法
public:
int wheels = 4; // 新增属性
void showSpec() { // 新增方法
cout << brand << " Car with " << wheels << " wheels" << endl;
}
};
// 使用示例:
Car myCar;
myCar.brand = "BMW"; // 继承自基类
myCar.honk(); // 调用基类方法
myCar.showSpec(); // 输出:BMW Car with 4 wheels
/*----------- 多态 (Polymorphism) -----------*/
class Shape { //一个形状
public:
virtual double area() { // 虚函数实现多态基础
return 0;
}
};
class Circle : public Shape { //圆
double radius;
public:
Circle(double r) : radius(r) {}
double area() override { // 重写基类方法
return 3.14159 * radius * radius;
}
};
class Rectangle : public Shape { //角度
double width, height;
public:
Rectangle(double w, double h) : width(w), height(h) {}
double area() override { // 重写基类方法
return width * height;
}
};
// 使用示例:
Shape* shapes[2]; // 基类指针数组
shapes[0] = new Circle(5); // 指向派生类对象
shapes[1] = new Rectangle(4, 6);
// 同一接口表现不同行为
cout << "Circle area: " << shapes[0]->area() << endl; // 输出78.5397
cout << "Rectangle area: " << shapes[1]->area() << endl; // 输出24
/* 多态实现关键点:
1. 基类方法声明为virtual
2. 派生类使用override重写方法
3. 通过基类指针/引用调用方法 */
// 清理动态分配的内存
delete shapes[0];
delete shapes[1];
return 0;
}
---
Buddy: Wang Wang!
Tu~ Tu~
BMW Car with 4 wheels
Circle area: 78.5397
Rectangle area: 24
三种访问权限
- 公共权限(public):公共成员可以在任何地方访问,包括类外部和派生类中。
示例:int publicVar; 可以在 main 函数中直接访问。 - 保护权限(protected):保护成员只能在本类和派生类中访问,不能在类外部访问。
示例:int protectedVar; 可以在派生类 Derived 中访问,但不能在 main 函数中直接访问。 - 私有权限(private):私有成员只能在本类中访问,不能在类外部和派生类中访问。
示例:int privateVar; 只能在 Base 类的成员函数中访问,不能在 main 函数和派生类 Derived 中直接访问。
#include <iostream>
#include <string>
using namespace std;
/*----------- 访问权限示例 -----------*/
class Base {
public:
int publicVar; // 公共权限:任何地方都可以访问
protected:
int protectedVar; // 保护权限:派生类和本类可以访问
private:
int privateVar; // 私有权限:只有本类可以访问
public:
// 构造函数
Base(int pub, int prot, int priv) : publicVar(pub), protectedVar(prot), privateVar(priv) {}
// 公共方法,访问私有成员
void showPrivateVar() {
cout << "Private Variable: " << privateVar << endl;
}
};
// 派生类
class Derived : public Base {
public:
// 构造函数
Derived(int pub, int prot, int priv) : Base(pub, prot, priv) {}
// 访问基类的保护成员
void showProtectedVar() {
cout << "Protected Variable: " << protectedVar << endl;
}
};
int main() {
// 创建基类对象
Base baseObj(1, 2, 3);
// 访问公共成员
cout << "Public Variable: " << baseObj.publicVar << endl;
// 访问私有成员(错误)
// cout << "Private Variable: " << baseObj.privateVar << endl; // 错误:无法访问私有成员
// 通过公共方法访问私有成员
baseObj.showPrivateVar();
// 创建派生类对象
Derived derivedObj(4, 5, 6);
// 访问基类的公共成员
cout << "Public Variable (Derived): " << derivedObj.publicVar << endl;
// 访问基类的保护成员(错误)
// cout << "Protected Variable (Derived): " << derivedObj.protectedVar << endl; // 错误:无法直接访问保护成员
// 通过派生类方法访问基类的保护成员
derivedObj.showProtectedVar();
return 0;
}
---
Public Variable: 1
Private Variable: 3
Public Variable (Derived): 4
Protected Variable: 5
struct 和 class的区别
在C++中,struct 和 class 的主要区别在于默认的访问控制权限。以下是详细的解释和示例代码:
区别
- 默认访问控制权限:
struct 的成员默认是 public。
class 的成员默认是 private。 - 继承:
struct 默认的继承方式是 public。
class 默认的继承方式是 private。
#include <iostream>
#include <string>
using namespace std;
// 使用 struct
struct MyStruct {
int publicVar; // 默认是 public
MyStruct(int val) : publicVar(val) {}
};
// 使用 class
class MyClass {
int privateVar; // 默认是 private
public:
MyClass(int val) : privateVar(val) {}
int getPrivateVar() const {
return privateVar;
}
};
int main() {
// 使用 struct
MyStruct s(10);
cout << "MyStruct publicVar: " << s.publicVar << endl; // 可以直接访问
// 使用 class
MyClass c(20);
// cout << "MyClass privateVar: " << c.privateVar << endl; // 错误:无法直接访问 private 成员
cout << "MyClass privateVar: " << c.getPrivateVar() << endl; // 通过公共方法访问
return 0;
}
---
MyStruct publicVar: 10
MyClass privateVar: 20
成员属性设置为私有
优点
- 封装性:将成员对象设置为私有可以隐藏对象的内部实现细节,只暴露必要的接口,增强了代码的封装性。
- 数据完整性:通过私有成员和公有方法,可以控制对数据的访问和修改,防止外部代码直接修改对象的状态,保证数据的完整性和一致性。
- 易于维护:由于内部实现细节被隐藏,修改内部实现不会影响外部代码,增强了代码的可维护性。
- 安全性:私有成员只能通过类的公有方法访问,减少了数据被意外或恶意修改的风险。
风险
- 性能开销:访问私有成员需要通过公有方法,这可能会带来一些性能开销,尤其是在频繁访问的情况下。
- 代码复杂性:为了访问和修改私有成员,需要编写额外的公有方法,可能会增加代码的复杂性。
- 灵活性降低:私有成员的访问受到限制,可能会降低代码的灵活性,某些情况下需要使用友元类或友元函数来访问私有成员。
#include <iostream>
#include <string>
using namespace std;
class PersonConnect { //通讯录类
private: //私有属性
string PName; //姓名
int PSex = 0; //性别 1 男 2 女
int PAge = 0; //年龄
string PPhone; //电话
string PAddress; //住址
public: //公有函数方法
// 设置姓名
void setName(const string& name) {
PName = name;
}
// 获取姓名
string getName() const {
return PName;
}
// 设置性别
void setSex(int sex) {
if (sex == 1 || sex == 2) {
PSex = sex;
}
else {
cout << "性别输入有误" << endl;
}
}
// 获取性别
int getSex() const {
return PSex;
}
// 设置年龄
void setAge(int age) {
PAge = age;
}
// 获取年龄
int getAge() const {
return PAge;
}
// 设置电话
void setPhone(const string& phone) {
PPhone = phone;
}
// 获取电话
string getPhone() const {
return PPhone;
}
// 设置地址
void setAddress(const string& address) {
PAddress = address;
}
// 获取地址
string getAddress() const {
return PAddress;
}
};
int main() {
PersonConnect person;
person.setName("张三");
person.setSex(1);
person.setAge(30);
person.setPhone("123456789");
person.setAddress("北京市");
cout << "姓名:" << person.getName() << endl;
cout << "性别:" << (person.getSex() == 1 ? "男" : "女") << endl;
cout << "年龄:" << person.getAge() << endl;
cout << "电话:" << person.getPhone() << endl;
cout << "地址:" << person.getAddress() << endl;
return 0;
}
---
姓名:张三
性别:男
年龄:30
电话:123456789
地址:北京市
练习案例1-设计立方体类
设计立方体类,求立方体面积和体积,分别用全局函数和成员函数判断两个立方体是否相等。
#include<iostream>
using namespace std;
/*
* 立方体类设计
* 1. 设计立方体类,求立方体的面积和体积
* 2. 分别用全局函数和成员函数判断两个立方体是否相等
*/
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_W * m_H + m_L * 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 true;
}
return false;
}
};
// 判断两个立方体是否相等(全局函数)
bool isSame(Cube& c1, Cube& c2)
{
if (c1.getL() == c2.getL() && c1.getW() == c2.getW() && c1.getH() == c2.getH())
{
return true;
}
return false;
}
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(10);
cout << "c2的面积为:" << c2.calculateS() << endl;
cout << "c2的体积为:" << c2.calculateV() << endl;
Cube c3;
c3.setL(20);
c3.setW(20);
c3.setH(20);
cout << "c3的面积为:" << c3.calculateS() << endl;
cout << "c3的体积为:" << c3.calculateV() << endl;
bool ret = c1.isSameByClass(c2); // 判断两个立方体是否相等(成员函数)
if (ret)
{
cout << "c1和c2相等" << endl;
}
else
{
cout << "c1和c2不相等" << endl;
}
bool ret2 = isSame(c1, c3); // 判断两个立方体是否相等(全局函数)
if (ret2)
{
cout << "c1和c3相等" << endl;
}
else
{
cout << "c1和c3不相等" << endl;
}
return 0;
}
/*
c1的面积为:600
c1的体积为:1000
c2的面积为:600
c2的体积为:1000
c3的面积为:2400
c3的体积为:8000
c1和c2相等
c1和c3不相等
*/
练习案例2-点和圆的关系
点在圈内,点在圆圈上,点在圆圈外。思路:设置圆类,圆心和半径;设置点,点坐标,求两点之间距离。
#include<iostream>
using namespace std;
/*
* 点在圈内,点在圆圈上,点在圆圈外。思路:设置圆类,圆心和半径;设置点,点坐标,求两点之间距离。
*/
class Point
{
public:
//设置点坐标
void setPoint(int x, int y)
{
Px = x;
Py = y;
}
//获取点坐标
int getPointX()
{
return Px;
}
int getPointY()
{
return Py;
}
private:
int Px; //点坐标
int Py;
};
class Clcle
{
public:
//设置圆心和半径
void setClcle(int x, int y, int r)
{
Cx = x;
Cy = y;
Cr = r;
}
//判断点在圆内,圆上,圆外
int judge(Point p)
{
int dis = (p.getPointX() - Cx) * (p.getPointX() - Cx) + (p.getPointY() - Cy) * (p.getPointY() - Cy);
if (dis < Cr * Cr)
{
return 1; //点在圆内
}
else if (dis == Cr * Cr)
{
return 0; //点在圆上
}
else
{
return -1; //点在圆外
}
}
private:
int Cx; //圆心坐标
int Cy;
int Cr; //半径
};
int main()
{
Point p;
p.setPoint(1, 1);
Clcle c;
c.setClcle(0, 0, 2);
int result = c.judge(p);
if (result == 1)
{
cout << "点在圆内" << endl;
}
else if (result == 0)
{
cout << "点在圆上" << endl;
}
else
{
cout << "点在圆外" << endl;
}
return 0;
}
___
点在圆内
🔔 想要获取更多网络安全与编程技术干货?
关注 泷羽Sec-静安 公众号,与你一起探索前沿技术,分享实用的学习资源与工具。我们专注于深入分析,拒绝浮躁,只做最实用的技术分享!💻
扫描下方二维码,马上加入我们,共同成长!🌟
👉 长按或扫描二维码关注公众号
或者直接回复文章中的关键词,获取更多技术资料与书单推荐!📚