I am new to C++ and I am having difficulties with getting the vector.erase operation to work.
我是C ++的新手,我在使vector.erase操作工作时遇到了困难。
I have a database class as such:
我有一个数据库类:
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);
};
and in practice, I am using the code as such:
在实践中,我使用的代码如下:
Database<Account> accountDatabase;
Account
is a base class, with two derived classes, ChequingAccount
and SavingsAccount
.
Account是一个基类,有两个派生类,ChequingAccount和SavingsAccount。
I am inserting accounts, regardless of type (could be Account
, ChequingAccount
, SavingsAccount
) into this database using:
我使用以下方法将帐户插入此数据库,无论其类型(可能是Account,ChequingAccount,SavingsAccount)
template <class T> void Database<T>::add(T object)
{
m_database.push_back(object);
++m_counter;
}
However, I am having issues with my delete operation. I am searching for a corresponding objectId
and then deleting it from the vector.
但是,我的删除操作有问题。我正在搜索相应的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;
}
}
}
Unfortunately the delete operation is not working at all. I am also having issues pulling a derived class from the database, as everything is being pulled out as an Account
type. I believe these two issues are tied to my noob C++ skills and bad design.
不幸的是,删除操作根本不起作用。我也有从数据库中提取派生类的问题,因为所有内容都被作为帐户类型提取出来。我相信这两个问题与我的noob C ++技能和糟糕的设计有关。
Any help would be greatly appreciated! Thanks!
任何帮助将不胜感激!谢谢!
EDIT
By not working, I mean the object is not deleted from the database. I apologize for any confusion.
如果不工作,我的意思是该对象不会从数据库中删除。我为任何困惑道歉。
The Account classes:
帐户类:
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) {}
}
2 个解决方案
#1
2
Note that your remove function would be far better in terms of std::remove_if
:
请注意,就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());
That said, your version does not look incorrect, just inefficient. What about it "doesn't work"? I do note that you maintain a separate object ID in your database but never actually put that ID into the objects you store.
也就是说,您的版本看起来不正确,效率低下。怎么样“不起作用”?我注意到您在数据库中维护一个单独的对象ID,但实际上从未将该ID放入您存储的对象中。
#2
1
Your del
function looks correct, only suggestion is instead of:
您的del函数看起来正确,只有建议而不是:
(*it).getId()
you can/should use:
你可以/应该使用:
it->getId()
which is simpler and more readable. So culprit is somewhere else. As for issue, that everything is pulled as Account
type, you have slicing problem, details read here What is object slicing?
这更简单,更易读。所以罪魁祸首就在别的地方。至于问题,所有内容都被拉为帐户类型,你有切片问题,详细信息请参阅此处什么是对象切片?
The fact that you make your class Database
a template does not change anything, you probably misunderstand what template does. Your Database<Account>
is nothing more than as you would use Account
instead of T
and not use template at all, and you insert objects, inherited from Account
by value.
您将类Database作为模板的事实不会改变任何内容,您可能会误解模板的作用。您的数据库 <帐户> 只不过是您使用帐户而不是T而根本不使用模板,并且您插入的对象继承自Account by value。
#1
2
Note that your remove function would be far better in terms of std::remove_if
:
请注意,就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());
That said, your version does not look incorrect, just inefficient. What about it "doesn't work"? I do note that you maintain a separate object ID in your database but never actually put that ID into the objects you store.
也就是说,您的版本看起来不正确,效率低下。怎么样“不起作用”?我注意到您在数据库中维护一个单独的对象ID,但实际上从未将该ID放入您存储的对象中。
#2
1
Your del
function looks correct, only suggestion is instead of:
您的del函数看起来正确,只有建议而不是:
(*it).getId()
you can/should use:
你可以/应该使用:
it->getId()
which is simpler and more readable. So culprit is somewhere else. As for issue, that everything is pulled as Account
type, you have slicing problem, details read here What is object slicing?
这更简单,更易读。所以罪魁祸首就在别的地方。至于问题,所有内容都被拉为帐户类型,你有切片问题,详细信息请参阅此处什么是对象切片?
The fact that you make your class Database
a template does not change anything, you probably misunderstand what template does. Your Database<Account>
is nothing more than as you would use Account
instead of T
and not use template at all, and you insert objects, inherited from Account
by value.
您将类Database作为模板的事实不会改变任何内容,您可能会误解模板的作用。您的数据库 <帐户> 只不过是您使用帐户而不是T而根本不使用模板,并且您插入的对象继承自Account by value。