C++学习之旅(三) - 运行项目

一, 银行账户管理系统拓展

项目概述

对之前的银行账户管理系统进行拓展,增加如下功能:

  1. 账户类型:支持不同类型的账户,比如储蓄账户和支票账户。
  2. 利息功能:为储蓄账户添加计算利息的功能。
  3. 透支保护:为支票账户添加透支保护功能。
  4. 账户列表:管理多个账户。

代码实现

#include <iostream>
#include <string>
#include <vector>

class BankAccount {
protected:
    std::string accountNumber;
    std::string accountHolder;
    double balance;

public:
    BankAccount(std::string number, std::string holder)
        : accountNumber(number), accountHolder(holder), balance(0.0) {}
    
    virtual void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
        }
    }

    virtual void withdraw(double amount) {
        if (amount > 0 && balance >= amount) {
            balance -= amount;
        }
    }

    virtual void displayAccount() const{
        std::cout << "Account Number: " << accountNumber << "\n"
                  << "Account Holder: " << accountHolder << "\n"
                  <<"Balance: " << balance << "\n";
    }

    virtual void addInterest() {}
    
};

class SavingsAccount : public BankAccount {
private:
    double interestRate;

public:
    SavingsAccount(std::string number, std::string holder, double rate)
        : BankAccount(number, holder), interestRate(rate) {}

    void addInterest() override {
        double interest = balance * interestRate / 100;
        deposit(interest);
    }
};

class CheckingAccount : public BankAccount {
private:
    double overdraftLimit;

public:
    CheckingAccount(std::string number, std::string holder, double limit)
        : BankAccount(number, holder), overdraftLimit(limit) {}

    void withdraw(double amount) override {
        if (amount > 0 && balance - amount >= - overdraftLimit) {
            balance -= amount;
        }
    }

};

int main() {
    std::vector<BankAccount*> accounts;
    accounts.push_back(new SavingsAccount("123445678", "张三", 3));
    accounts.push_back(new CheckingAccount("87654321", "里斯", 500));

    accounts[0]->deposit(1000);
    accounts[0]->addInterest();
    accounts[1]->deposit(500);
    accounts[1]->withdraw(1000);

    for (BankAccount* account : accounts) {
        account->displayAccount();
    }

    for (BankAccount* account : accounts) {
        delete account;
    }

    return 0;

}

项目解析

  1. 类的继承和多态SavingsAccountCheckingAccount 继承自 BankAccount 类,并重写了一些方法来实现特定的功能。
  2. 虚函数addInterestwithdraw 是虚函数,允许在派生类中被重写以实现不同的行为。
  3. 账户类型:通过继承和多态,支持不同类型的账户。
  4. 利息计算SavingsAccount 类中的 addInterest 方法用于计算利息。
  5. 透支保护CheckingAccount 类重写了 withdraw 方法,以提供透支保护。
  6. 管理多账户:使用 std::vector<BankAccount*> 来存储和管理不同的账户。
  7. 资源管理:使用 new 在堆上创建对象,并在最后使用 delete 释放内存。

部分代码片段解释

1.protected

在C++中,`protected` 关键字是一个访问修饰符,用于控制对类成员的访问权限。`protected` 修饰符在继承关系中起着特殊作用:

1. **对于类本身和友元类**:`protected` 成员就像 `private` 成员一样,只能被类本身的成员函数、类的构造函数、析构函数、友元类的成员函数访问。

2. **对于派生类**:`protected` 成员可以被派生类(子类)访问。这是与 `private` 的主要区别。使用 `protected` 修饰符允许子类访问和修改这些成员,同时仍然隐藏这些成员不被类的外部访问。

在我们之前的银行账户管理系统例子中,`BankAccount` 类中的 `accountNumber`、`accountHolder` 和 `balance` 成员被声明为 `protected`。这意味着这些成员可以在 `BankAccount` 类及其派生类(如 `SavingsAccount` 和 `CheckingAccount`)中被直接访问和修改,但对于其他类则是不可见的。

使用 `protected` 而非 `private` 是面向对象设计中的一个常见做法,它在保持封装性的同时,又提供了一定的灵活性,使得派生类能够更方便地使用和扩展基类的功能。、

2.virtual

在C++中,`virtual` 关键字用于声明函数为“虚函数”。这对实现多态性,即在继承体系中的不同类对象能表现出不同行为,至关重要。在基类中声明一个函数为 `virtual` 意味着派生类可以重写该函数,以提供特定于派生类的行为。

1,  作用
- **允许在派生类中重写**:如果在基类中有一个 `virtual` 函数,派生类可以重写该函数以实现不同的功能。
- **动态绑定**:当使用基类的指针或引用调用虚函数时,将会根据对象的实际类型来调用相应的函数版本。这种行为在运行时确定,因此称为动态绑定。

2. 示例
在之前的银行账户例子中,`virtual void addInterest()` 函数在 `BankAccount` 类中被声明为虚函数。这意味着我们可以在任何继承自 `BankAccount` 的子类中重写 `addInterest` 函数。

在 `SavingsAccount` 类中,我们重写了 `addInterest` 函数,以实现特定于储蓄账户的利息计算逻辑。这样,当我们调用 `addInterest` 函数时,如果对象是 `SavingsAccount` 类型的实例,那么将调用 `SavingsAccount` 中重写的 `addInterest` 函数。如果对象是 `BankAccount` 类型或其他未重写 `addInterest` 函数的派生类的实例,将调用 `BankAccount` 类中的 `addInterest` 函数。

3. 重要点
- 声明为 `virtual` 的函数通常有一个在基类中的默认实现,但它们主要是为了在派生类中被重写。
- 如果在派生类中重写虚函数,最好使用 `override` 关键字明确表示。这增加了代码的可读性,并帮助编译器检查重写的正确性。
- 在析构函数中使用 `virtual` 是多态类层次结构中的一个重要和常见做法,以确保通过基类指针删除派生类对象时,能够调用正确的析构函数。

3. main()函数

1. 创建账户对象
  • std::vector<BankAccount*> accounts;:定义了一个 BankAccount 指针的向量(动态数组)。
  • accounts.push_back(new SavingsAccount("123445678", "张三", 3));:创建一个 SavingsAccount 对象,并将其地址存入 accounts 向量。这里 "123445678" 是账户号码,"张三" 是账户持有人,3 是利率。
  • accounts.push_back(new CheckingAccount("87654321", "里斯", 500));:类似地,创建一个 CheckingAccount 对象。
 2. 操作账户
  • 使用指针访问运算符 -> 来调用 BankAccount 对象的方法。
  • 对第一个账户(储蓄账户)进行存款和计算利息。
  • 对第二个账户(支票账户)进行存款和取款。
3. 显示账户信息

遍历 accounts 向量中的每个账户,调用它们的 displayAccount 方法来显示信息。

4. 清理资源
  • 这个循环遍历 accounts 向量,并释放每个账户对象占用的堆内存。
  • 在C++中,使用 new 分配的内存必须显式地使用 delete 释放,以防内存泄漏。

  • 22
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值