手把手教你学C++(二十七)--C++数据封装

目录

访问控制

示例:使用访问控制实现数据封装

封装的好处

封装的注意事项

示例:使用保护成员实现封装

小结


 

数据封装(Encapsulation)是面向对象编程中的一个重要原则,它指的是将数据成员(属性)和成员函数(方法)捆绑在一个类中,并控制对外部的访问权限。数据封装的目标是隐藏类的内部实现细节,并提供一个清晰的外部接口,从而保护数据不被外部代码直接访问或修改,增加代码的安全性和稳定性。

在 C++ 中,数据封装主要通过以下几种机制实现:

访问控制

C++ 提供了三种访问控制级别:publicprivateprotected

  • public:公有成员可以被类的外部代码访问。
  • private:私有成员只能被类的成员函数访问,不能被类外的代码直接访问。
  • protected:受保护成员类似于私有成员,但派生类可以访问基类的受保护成员。

示例:使用访问控制实现数据封装

 

cpp

深色版本

#include <iostream>
using namespace std;

class BankAccount {
private:
    double balance; // 私有数据成员

public:
    // 构造函数
    BankAccount(double initialBalance) : balance(initialBalance) {}

    // 存款
    void deposit(double amount) {
        balance += amount;
    }

    // 取款
    bool withdraw(double amount) {
        if (balance >= amount) {
            balance -= amount;
            return true;
    }
        cout << "Insufficient funds" << endl;
        return false;
    }

    // 获取余额
    double getBalance() const {
        return balance;
    }

    // 设置余额(通常应避免直接提供设置函数,这里仅为示例)
    void setBalance(double newBalance) {
        balance = newBalance;
    }
};

int main() {
    BankAccount account(1000.0); // 创建一个银行账户

    account.deposit(500.0); // 存款 500
    cout << "Current Balance: " << account.getBalance() << endl; // 输出 Current Balance: 1500

    if (account.withdraw(200.0)) { // 取款 200
        cout << "Withdrawal successful." << endl;
    }
    cout << "Current Balance: " => account.getBalance() << endl; // 输出 Current Balance: 1300

    // 尝试直接访问私有成员(编译错误)
    // cout << "Direct access: " << account.balance << endl;

    // 使用设置函数(不推荐)
    account.setBalance(2000.0);
    cout << "Updated Balance: " << account.getBalance() << endl; // 输出 Updated Balance: 2000

    return 0;
}

在这个例子中,BankAccount 类的 balance 数据成员是私有的,只能通过成员函数 depositwithdrawgetBalance 来访问。这样就实现了数据的封装。

封装的好处

数据封装带来的好处包括:

  • 安全性:由于数据成员被隐藏起来,外部代码无法直接修改这些数据成员,减少了由于错误操作导致的问题。
  • 一致性:通过成员函数来访问数据成员,可以确保数据的一致性,例如在存款或取款时进行验证。
  • 可维护性:内部实现的变化不会影响到外部代码,只要外部接口不变,内部的改动不会影响到其他部分。
  • 灵活性:可以通过添加新的成员函数来扩展类的功能,而不必改变现有的代码。

封装的注意事项

在实现数据封装时需要注意以下几点:

  • 避免直接暴露私有成员:尽量不要提供可以直接访问私有成员的公共函数,除非必要。
  • 合理使用保护成员:保护成员可以被派生类访问,这对于继承和多态非常有用。
  • 合理设计接口:设计清晰、简洁的公共接口,只暴露必要的功能。

示例:使用保护成员实现封装

 

cpp

深色版本

#include <iostream>
using namespace std;

class Base {
protected:
    int value;

public:
    Base(int val) : value(val) {}
};

class Derived : public Base {
public:
    Derived(int val) : Base(val) {}

    // 在派生类中可以访问基类的保护成员
    void increment() {
        value++;
    }

    // 获取值
    int getValue() const {
        return value;
    }
};

int main() {
    Derived d(10);
    d.increment();
    cout << "Value after increment: " << d.getValue() << endl; // 输出 Value after increment: 11

    // 直接访问保护成员(编译错误)
    // cout << "Direct access to protected member: " << d.value << endl;

    return 0;
}

在这个例子中,Base 类的 value 是受保护的成员,可以在 Derived 类中访问,但不能被外部代码直接访问。

小结

数据封装是面向对象编程中的一个重要概念,它通过控制类的成员的访问权限来实现数据的隐藏和保护。在 C++ 中,通过使用 publicprivateprotected 关键字来实现数据封装。理解并正确应用数据封装的原则,可以帮助你编写出更安全、更稳定的代码。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值