我是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
是一个基类,有两个派生类ChequingAccount
和SavingsAccount
。
我使用以下方式将帐户插入此数据库,无论其类型(可能是Account
,ChequingAccount
,SavingsAccount
)如何
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) {}
}
答案 0 :(得分:2)
请注意,就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放入您存储的对象中。
答案 1 :(得分:1)
您的del
功能看起来是正确的,只有建议而不是:
(*it).getId()
你可以/应该使用:
it->getId()
更简单,更易读。所以罪魁祸首就在别的地方。至于问题,一切都是Account
类型,你有切片问题,详情请阅读What is object slicing?
将类Database
作为模板的事实并没有改变任何内容,您可能会误解模板的作用。您的Database<Account>
只不过是使用Account
代替T
而不是使用模板,而是插入按值从Account
继承的对象。