【问题标题】:C++ OOP Abstract Class - Access violation writing locationC++ OOP 抽象类 - 访问冲突写入位置
【发布时间】:2022-01-04 14:42:19
【问题描述】:

我有一个UserAcount 类,它有一个抽象类ContBancar,还有一个类Banca 从文件中读取一些用户(使用方法void Banca::citire_conturi())。当它读取用户时,我在ContBancarvoid setBal(double bal) { _balanta = bal; } 中收到错误“访问冲突写入位置”。谢谢帮忙!

PS:文件只有一行:1CBS Dragos 0 dragos12! Gzpvia01=。 另外,我想制作一个银行账户系统,它的用户类有一个银行账户类,它继承了 3 种银行账户类型,还有一个银行类,它从文件中读取一些用户或将它们放在上面。

 class UserAccount
{
private:
    std::string _nume, _user, _pass;
    std::string _cod_us;
    std::shared_ptr <ContBancar> _cont; 

public:
    void setUser(std::string user) { _user = user; }
    void setPass(std::string pass) { _pass = pass; }
    void setNume(std::string nume) { _nume = nume; }
    void setCodUs(std::string cod) { _cod_us = cod; }
    void setContBal(double balanta) { (*_cont).setBal(balanta); }
    std::string getUser() const { return _user; }
    std::string getPass() const { return _pass; }
    std::string getNume() const { return _nume; }
    std::string getCodUs() const { return _cod_us; }
    double getContBal() const { return (*_cont).getBal(); }
    void setContBancar();
};

void UserAccount::setContBancar()
{
    if (_cod_us == "1CBS")
        _cont.reset(new ContBancarSilver());
    else if (_cod_us == "2CBG")
        _cont.reset(new ContBancarGold());
    else
        _cont.reset(new ContBancarDiamond());
}


class ContBancar
{
protected:
    double _balanta;

public:
    void setBal(double bal) { _balanta = bal; }
    double getBal() { return _balanta; }
    virtual bool depozitare(unsigned int) = 0;
    virtual bool retragere(unsigned int) = 0;
};


class Banca
{
private:
    std::vector<UserAccount> vec;
public:
    void citire_conturi();
};

void Banca::citire_conturi()
{
    std::ifstream file;
    file.open("Baza_Date.txt");

    UserAccount temp;
    std::string cod, nume, user, pass;
    double balanta;

    while (file >> cod >> nume >> balanta >> user >> pass)
    {
        temp.setCodUs(cod);
        temp.setNume(nume);
        temp.setContBal(balanta);
        temp.setUser(user);
        temp.setPass(pass);
        vec.push_back(temp);
    }

    file.close();
}


class ContBancarSilver : public ContBancar
{
private:
    static constexpr unsigned int max_balanta = 5000;
    static constexpr unsigned int max_depozitare = 2500;
    static constexpr unsigned int max_retragere = 1000;
    static constexpr double tax_retragere = 0.08;
    static constexpr double bonus_depunere = 0.03;
    static constexpr double bonus_tax_retragere = 0.05;
    static constexpr unsigned int max_depozitari = 1;
    static constexpr unsigned int max_retrageri = 1;

public:
    virtual bool depozitare(unsigned int) override;
    virtual bool retragere(unsigned int) override;
};

【问题讨论】:

  • _cont 从未初始化,因此它包含nullptr!所以setContBal 调用未定义的行为。继承ContBancar并实现抽象的类在哪里?
  • 顺便说一句:总是用英文编码,这样每个人都可以阅读和理解你的代码。
  • 我认为你不需要用英文编码。获得帮助可能更容易,但我认为这并不重要。
  • 您可能希望 ro 阅读更多关于如何使用 shared_ptr 及其用途的信息。例如,您为什么要分享ContBancar,以及与谁分享?
  • @floomby 非常糟糕的建议。他越早开始用英语编写代码就越好。即使是残缺的英语版本也会更好。如果您学会使用您的母语,那么以后将很难切换到英语。如果您更喜欢用您的母语编写代码,您可以将薪水除以 2 或 3。

标签: c++ oop abstract-class


【解决方案1】:

根据可用信息,您应该像这样修复您的代码:

class UserAccount
{
    .....
    void setCodUs(std::string cod) {
        _cod_us = cod;
        setContBancar();
    }
    void setContBal(double balanta) {
        if (!_cont) setContBancar(); // lazy initialization
        _cont->setBal(balanta);
    }
    ...
};

void UserAccount::setContBancar()
{
    if (_cod_us == "1CBS")
        _cont = std::make_shared<ContBancarSilver>();
    else if (_cod_us == "2CBG")
        _cont = std::make_shared<ContBancarGold>();
    else
        _cont = std::make_shared<ContBancarDiamond>();
}

注意我不明白你正在实现什么样的逻辑。此更改只是确保 _cont 已初始化并与 _cod_us 保持同步。

请明确停止使用newdelete。一切都可以由std::make_sharedstd::make_unique 以及像std::vector 这样的容器创建。

【讨论】:

  • void UserAccount::setContBancar() 使用此功能我希望我的用户使用他们银行帐户类型中的方法(如果 Ana 有 ContBancarSilver,她有不同的成员值,如税等,这会导致覆盖方法)。有意义吗?
  • 我不明白你为什么使用“延迟初始化”
  • 是设计模式:使用前不要初始化。
猜你喜欢
  • 1970-01-01
  • 2018-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多