【问题标题】:Erase operation on vector not working矢量上的擦除操作不起作用
【发布时间】:2014-09-23 19:32:08
【问题描述】:

我是 C++ 新手,在让 vector.erase 操作正常工作时遇到困难。

我有一个这样的数据库类:

template <class T> class Database
{
    protected:
        std::vector<T> m_database;
        int m_counter;
    public:
        Database();
        virtual ~Database();

        // Accessor Methods.
        T& getObject(int objectId);
        bool exists(int objectId);

        // Mutator Methods.
        void add(T Object);
        void del(int objectId);
};

实际上,我是这样使用代码的:

Database<Account> accountDatabase;

Account 是一个基类,有两个派生类ChequingAccountSavingsAccount

我正在使用以下方法将帐户(可能是AccountChequingAccountSavingsAccount)插入到此数据库中:

template <class T> void Database<T>::add(T object)
{
    m_database.push_back(object);
    ++m_counter;
}

但是,我的删除操作有问题。我正在搜索相应的objectId,然后将其从向量中删除。

// Deletes the specified object from the database.
template <class T> void Database<T>::del(int objectId)
{
    std::vector<T>& database             = m_database;
    typename std::vector<T>::iterator it = database.begin();

    while (it != database.end()) {
        if ((*it).getId() == objectId) {
            it = database.erase(it);
        } else {
            ++it;
        }
    }
}

不幸的是,删除操作根本不起作用。我在从数据库中提取派生类时也遇到问题,因为所有内容都作为Account 类型提取。我相信这两个问题与我的菜鸟 C++ 技能和糟糕的设计有关。

任何帮助将不胜感激!谢谢!

编辑

不工作,我的意思是对象没有从数据库中删除。对于任何混淆,我深表歉意。

帐户类:

class Account
{
    protected:
        int m_id;
        double m_balance;
        std::string m_name, m_type;
    public:
        Account(int id, int userId, double balance = 0, std::string name = ""); // Constructor.
        ~Account(); // Destructor.

        // Accessor Methods.
        // This returns m_id AKA objectId
        int getId() const;
}

class ChequingAccount: public Account
{
    public:
        ChequingAccount(int id, int userId, double balance, std::string name) : Account(id, userId, balance, name) {}
}

class SavingsAccount: public Account
{
    public:
        SavingsAccount(int id, int userId, double balance, std::string name) : Account(id, userId, balance, name) {}
}

【问题讨论】:

  • 1. “根本不工作”是什么意思? 2. 为什么不用std::remove
  • 发布帐户可能会有所帮助
  • deleting while iterating 的可能重复项
  • @Raymond 这略有不同,因为用户正确地将迭代器结果从调用std::vector&lt;t&gt;::erase(iterator)重新分配
  • 您的del() 看起来不错,所以不妨检查一下您的id 是否正确?

标签: c++ templates inheritance vector


【解决方案1】:

请注意,您的删除功能在std::remove_if 方面会好得多:

auto endIterator = std::remove_if(m_database.begin(), m_database.end(),
    [=](T const& entry) { return entry.getId() == objectId; }
    );
m_database.erase(endIterator, m_database.end());

也就是说,您的版本看起来并没有错误,只是效率低下。它“不起作用”怎么办?我确实注意到您在数据库中维护了一个单独的对象 ID,但实际上从未将该 ID 放入您存储的对象中。

【讨论】:

  • 旧的“擦除/删除”习语
  • 假设我的方法是“正确的”,应该是我的 objectId 给了我问题?
  • @user3745117 你从来没有显示 ID 是如何进入 T 的,所以我们不知道。
  • @BillyONEal 我已经编辑了我的问题以包含这些课程。
【解决方案2】:

您的del 函数看起来正确,唯一的建议是:

(*it).getId()

你可以/应该使用:

it->getId()

更简单,更易读。所以罪魁祸首在别处。至于问题,所有东西都被拉成Account类型,你有切片问题,详细阅读这里What is object slicing?

你将你的类Database 设为模板这一事实并没有改变任何东西,你可能误解了模板的作用。您的Database&lt;Account&gt; 只不过是您将使用Account 而不是T 并且根本不使用模板,并且您插入对象,从Account 按值继承。

【讨论】:

  • 是的,我怀疑这是丢失派生类型的情况。但是,我无法让指针向量正常工作。我想我会再试一次
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多