c++总复习

1. 什么是封装性

封装性(Encapsulation)是面向对象编程(Object-Oriented Programming,OOP)中的一个重要概念,它指的是将数据(通常是类的成员变量)和操作这些数据的方法(类的成员函数)组合在一起,并对外部隐藏数据的具体实现细节,只通过特定的接口(类的公有成员函数)来访问和操作这些数据。简单来说,就像是把相关的东西放在一个 "黑盒子" 里,外部使用者不需要知道里面具体是怎么运作的,只需要按照规定好的方式去使用它就能达成目的。

例如,设计一个表示银行账户的类,账户的余额信息就是内部的数据,而存钱、取钱这些操作就是与之相关的方法。外部用户不需要知道余额具体是怎么在内部存储和计算的,只需要通过提供的存钱、取钱等公有方法就能对账户进行相应操作,这就体现了封装性。

2. C++ 中如何实现封装

在 C++ 中,主要通过类(class)来实现封装,具体有以下几个关键要素:

(1)访问修饰符

C++ 提供了三种访问修饰符:public(公有)、private(私有)和 protected(受保护)。

  • public
    公有成员(包括成员函数和成员变量,不过一般尽量少让成员变量为公有,更多是公有成员函数)可以在类的外部被访问。例如:
cpp 复制代码
class Rectangle {
public:
    int getWidth() { return width; }
    int getHeight() { return height; }
private:
    int width;
    int height;
};

在上述代码中,getWidthgetHeight 这两个公有成员函数可以被类外部的代码调用,用于获取 Rectangle 类中私有成员变量 widthheight 的值。

  • private
    私有成员只能在类的内部被访问,外部代码无法直接访问私有成员变量或调用私有成员函数。就像上面代码中的 widthheight,它们被声明为私有,只能通过类内部的公有函数(如 getWidthgetHeight)来间接操作它们。这样就把数据隐藏起来了,保证了数据的安全性和封装性。

  • protected
    受保护成员的访问权限介于公有和私有之间,它在类内部可以正常访问,同时在派生类(继承该类的子类)中也能被访问,但在类的外部(非派生类的其他代码处)不能被访问。常用于在继承体系中,让子类可以访问父类的部分成员,同时又对外界保持一定的隐藏性。例如:

    class Shape {
    protected:
    int color;
    public:
    void setColor(int c) { color = c; }
    };

    class Circle : public Shape {
    public:
    void changeColor(int newColor) {
    color = newColor; // 在派生类中可以访问受保护的成员color
    }
    };

(2)类的定义和使用

定义一个类时,将相关的数据成员声明为合适的访问权限(一般数据成员多为私有或受保护),并提供公有成员函数作为与外部交互的接口。然后在类外部使用对象时,只能通过这些公有接口来操作对象的数据。例如:

class Person {
private:
    std::string name;
    int age;
public:
    Person(const std::string& n, int a) : name(n), age(a) {}
    void introduce() {
        std::cout << "My name is " << name << ", and I'm " << age << " years old." << std::endl;
    }
};

int main() {
    Person p("Alice", 25);
    p.introduce();  // 通过公有成员函数introduce来展示对象相关信息,不能直接访问私有成员name和age
    return 0;
}

3. 封装性的好处

(1)数据隐藏与安全性

封装把类的内部数据隐藏起来,外部代码不能随意修改,只能通过类提供的合法接口去操作数据。这样可以防止外部代码意外地或者恶意地破坏对象内部数据的完整性和一致性。比如对于一个管理数据库连接的类,内部的连接字符串、用户名、密码等敏感信息设置为私有,外部无法直接访问修改,只有通过类提供的经过安全验证等设计的连接、断开连接等接口去操作,保障了数据安全。

(2)提高代码的可维护性

当类的内部实现需要修改时,只要对外的接口保持不变,那么使用这个类的其他代码(可能在不同的模块甚至不同的项目中)通常不需要做相应改动。例如,一个实现栈数据结构的类,最初内部用数组来存储元素,后面为了提高性能想改成用链表来存储元素,只要 push(入栈)、pop(出栈)等对外的公有接口函数功能和参数不变,使用这个栈类的其他代码就能正常工作,大大降低了代码维护的难度和成本。

(3)便于代码的复用

封装好的类可以方便地在不同的项目或者模块中被复用。因为使用者只需要了解其对外提供的接口功能,不需要关心内部具体实现细节,只要符合使用场景就可以直接拿来使用。比如一个实现了常用数学运算功能(如求最大公因数、最小公倍数等)的类,其他需要进行这些数学运算的程序都可以复用这个类,而不用重新去编写相关的运算代码。

(4)增强代码的模块化

通过封装,不同的类可以看作是不同的模块,每个模块有自己独立的数据和操作这些数据的方法,模块之间通过接口进行交互,这样使得整个程序的结构更加清晰,各个模块的职责明确,易于理解和开发,符合软件工程中模块化开发的理念,提高了大型项目开发的效率和质量。

相关推荐
姓学名生4 分钟前
李沐vscode配置+github管理+FFmpeg视频搬运+百度API添加翻译字幕
vscode·python·深度学习·ffmpeg·github·视频
半盏茶香20 分钟前
扬帆数据结构算法之雅舟航程,漫步C++幽谷——LeetCode刷题之移除链表元素、反转链表、找中间节点、合并有序链表、链表的回文结构
数据结构·c++·算法
是梦终空21 分钟前
JAVA毕业设计210—基于Java+Springboot+vue3的中国历史文化街区管理系统(源代码+数据库)
java·spring boot·vue·毕业设计·课程设计·历史文化街区管理·景区管理
哎呦,帅小伙哦28 分钟前
Effective C++ 规则41:了解隐式接口和编译期多态
c++·effective c++
基哥的奋斗历程1 小时前
学到一些小知识关于Maven 与 logback 与 jpa 日志
java·数据库·maven
m0_512744641 小时前
springboot使用logback自定义日志
java·spring boot·logback
十二同学啊1 小时前
JSqlParser:Java SQL 解析利器
java·开发语言·sql
老马啸西风1 小时前
Plotly 函数图像绘制
java
DARLING Zero two♡1 小时前
【初阶数据结构】逆流的回环链桥:双链表
c语言·数据结构·c++·链表·双链表
9毫米的幻想1 小时前
【Linux系统】—— 编译器 gcc/g++ 的使用
linux·运维·服务器·c语言·c++