You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++银行项目中避免重复传递Customer对象引用?

银行服务代码优化方案

你当前的核心问题是:accounts和transactions作为Customer的成员类,却需要在每个方法里重复传递Customer引用才能访问所属客户的数据。继承思路行不通是因为继承是"is-a"关系,账户/交易不是客户,它们是客户"拥有"的对象(has-a关系),所以正确的方向是让成员类持有所属客户的引用或指针,或者调整类的职责划分。

下面提供两种可行的优化方案:


方案一:让成员类持有所属客户的指针(推荐,保持职责分离)

给accounts和transactions添加一个指向所属Customer的指针,在构造时完成关联,这样方法里就无需再传递Customer参数。

修改步骤:

  1. 更新accounts类:
    添加私有指针成员,构造函数传入客户指针,移除方法中的Customer参数:

    class Customer; // 前置声明
    
    class accounts
    {
    private:
        Customer* owner; // 指向所属客户
    public:
        int acc_no;
        std::string acc_password;
    
        // 构造函数关联客户
        accounts(Customer* cust) : owner(cust) {}
    
        void details() const
        {
            // 直接通过owner访问客户数据
            std::cout << "Your Account number is: " << owner->acc.acc_no << std::endl;
            std::cout << "Your Account password is: " << owner->acc.acc_password << std::endl;
        }
    
        void add();
        void bal(); // 移除Customer参数
    };
    
  2. 更新transactions类:
    同样添加客户指针,修复原构造函数的数组越界问题(原代码transHis[3]会访问超出数组范围的内存):

    class Customer; // 前置声明
    
    class transactions
    {
    private:
        Customer* owner;
    public:
        int transHis[3];
    
        transactions(Customer* cust) : owner(cust)
        {
            // 正确初始化数组所有元素为0
            std::fill(std::begin(transHis), std::end(transHis), 0);
        }
    
        // 移除所有方法的Customer参数
        void transfer(int amt, int to_acc_no);
        void withdraw(int amt);
        void deposit(int amt);
        void updateHis(int amt);
        void showTransHis();
    };
    
  3. 更新Customer类:
    在构造函数中初始化acc和trans,传入自身指针:

    class Customer
    {
    public:
        std::string name;
        accounts acc;
        transactions trans;
        
        // 构造函数初始化成员类,关联自身
        Customer() : acc(this), trans(this) {}
    
        void details() const
        {
            std::cout << "Your Account number is: " << this->acc.acc_no << std::endl;
        }
    
        void create_cust(); // 移除Customer参数,直接操作自身成员
    };
    
  4. 更新BankingServices类:
    调用方法时不再需要传递Customer参数:

    void services()
    {
        int val;
        std::cout << "Enter 1 to withdraw money                 " << "Enter 2 to deposit money" << std::endl;
        std::cout << "Enter 3 to transfer money                 " << "Enter 4 to check acccount balance" << std::endl;
        std::cout << "Enter 5 to see transaction history        " << "Enter 6 to fetch account details" << std::endl;
        std::cin >> val;
    
        if (val == 1)
        {
            int amt;
            std::cout << "Enter Amount to be withdrawn: ";
            std::cin >> amt;
            this->cust.trans.withdraw(amt); // 无需传cust
        }
        else if (val == 2)
        {
            int amt;
            std::cout << "Enter amount to be deposited: ";
            std::cin >> amt;
            this->cust.trans.deposit(amt); // 无需传cust
        }
        // ... 其他分支同理修改
    }
    

方案二:将成员类的方法合并到Customer类(入门友好,代码更简洁)

如果是入门项目,不需要严格的职责分离,可以把accounts和transactions的核心逻辑直接移到Customer类中,让Customer直接管理自己的账户和交易:

修改示例:

class Customer
{
public:
    std::string name;
    int acc_no;
    std::string acc_password;
    int transHis[3];
    
    Customer()
    {
        std::fill(std::begin(transHis), std::end(transHis), 0);
    }

    void showAccountDetails() const
    {
        std::cout << "Your Account number is: " << acc_no << std::endl;
        std::cout << "Your Account password is: " << acc_password << std::endl;
    }

    void withdraw(int amt)
    {
        // 实现取款逻辑,直接操作自身数据
        // 比如更新余额、添加交易记录
        transHis[0] = -amt; // 示例:负号表示支出
    }

    void deposit(int amt)
    {
        transHis[0] = amt; // 示例:正号表示收入
    }

    void showTransactionHistory() const
    {
        std::cout << "Transaction History: ";
        for (int i = 0; i < 3; ++i)
        {
            std::cout << transHis[i] << " ";
        }
        std::cout << std::endl;
    }

    void create_cust(); // 直接操作自身成员
};

这样BankingServices调用时直接调用Customer的方法,完全不需要传参:

this->cust.withdraw(amt);
this->cust.showAccountDetails();

补充说明:

  • 原代码中transactions构造函数的transHis[3] = {0};是错误的,数组大小为3,索引范围是0-2,访问索引3会导致数组越界,建议用std::fill或循环初始化所有元素。
  • 继承思路不适用的原因:accounts和transactions是Customer的组成部分,不是"一种"客户,所以用组合(has-a)而非继承(is-a)才是正确的设计。

内容的提问来源于stack exchange,提问作者Kovidh V.S. Bhati

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 09:33:10