상속 목적을위한 포인터 벡터를 사용하고 있으며 모든 동작을해야하지만 벡터에서 개체를 삭제하는 데 문제가 있습니다.C++ 포인터의 벡터에서 요소 지우기
내가 쉽게 컴파일하고 실행하기위한 메이크과 함께 모든 소스 파일이있는 Github에서의 요점을 만든:
나는 은행 클래스가 : 기본적으로 여기
https://gist.github.com/anonymous/7c689940992f5986f51e
문제입니다 (계정 데이터베이스 구조 인 캡슐화 된 계정 *에 유의하십시오.)
class Bank
{
private:
Database<Account> m_acctDb;
Database<User> m_userDb;
int m_accountCounter;
int m_userCounter;
public:
Bank();
~Bank();
// Accessor Methods.
int getAccountCounter() const;
int getUserCounter() const;
int getNumAccounts() const;
int getNumUsers() const;
Database<Account> getAccountDatabase() const;
Database<User> getUserDatabase() const;
User *getUser (int userId);
Account *getAccount (int accountId);
std::vector<ChequingAccount> getChequingAccounts() const;
std::vector<SavingsAccount> getSavingsAccounts() const;
std::vector<Manager> getManagers() const;
std::vector<Customer> getCustomers() const;
std::vector<Maintenance> getMaintenance() const;
// Mutator Methods.
void addChequing (int userId, double balance = 0, std::string name =
"");
void addSavings (int userId, double balance = 0,
std::string name = "");
void addCustomer (std::string firstName, std::string lastName,
std::string password, std::string username);
void addManager (std::string firstName, std::string lastName,
std::string password, std::string username);
void addMaintenance (std::string firstName, std::string lastName,
std::string password, std::string username);
void deleteAccount (int accountId);
void deleteUser (int userId);
};
나는 포인터의 벡터 생성과 같은 mplate 데이터베이스 클래스 : 내 은행에서
template<class T>
class Database
{
protected:
std::vector<T*> m_database;
public:
Database();
virtual ~Database();
std::vector<T*> getDatabase() const;
void add (T *Object);
bool del (int id);
};
를, 내가 계정과 같은 정의 개체를 추가하고 :
class Account
{
protected:
int m_id, m_userId, m_type;
double m_balance;
std::string m_name;
std::vector<std::string> m_history;
public:
Account (int id, int userId, double balance = 0,
std::string name = "");
virtual ~Account();
// Accessor Methods.
int getId() const;
int getUserId() const;
int getType() const;
double getBalance() const;
std::string getName() const;
std::string getDetails() const;
std::vector<std::string> getHistory() const;
// Mutator Methods.
void setName (std::string name);
void depositFunds (double amount);
virtual bool withdrawFunds (double amount);
};
/*
* Chequing account type
*/
class ChequingAccount : public Account
{
public:
ChequingAccount (int id, int userId, double balance = 0,
std::string name = "") :
Account(id, userId, balance, name)
{
// Chequing account type.
m_type = CHEQ;
// If no name was given.
if (name == "")
{
// Give account a generic name.
m_name = "Chequing Account #" + std::to_string(id);
}
else
{
m_name = name;
}
}
~ChequingAccount()
{
}
virtual bool withdrawFunds (double amount);
};
/*
* Savings account type
*/
class SavingsAccount : public Account
{
public:
SavingsAccount (int id, int userId, double balance, std::string name) :
Account(id, userId, balance, name)
{
// Savings account type.
m_type = SAVE;
// If no name was given.
if (name == "")
{
// Give account a generic name.
m_name = "Savings Account #" + std::to_string(id);
}
else
{
m_name = name;
}
}
~SavingsAccount()
{
}
};
내가 계정 개체를 추가하고를, 같은 은행에, 기본 계정 클래스에서 클래스를 파생 주로 Chequing/저축 계정 :
/*
* Adds a new chequing account to the bank database.
*/
void Bank::addChequing (int userId, double balance, std::string name)
{
m_acctDb.add(new ChequingAccount(++m_accountCounter, userId, balance, name));
}
/*
* Adds a new savings account to the bank database.
*/
void Bank::addSavings (int userId, double balance, std::string name)
{
m_acctDb.add(new SavingsAccount(++m_accountCounter, userId, balance, name));
}
이 모두 제대로 작동하고, 나는 데이터베이스와 m에서 물체를 끌어 당길 수 있어요 내가 좋아하는 방식으로 발랐다.
/*
* Deletes the specified account from the bank database.
*/
void Bank::deleteAccount (int accountId)
{
std::vector<Account*> db = m_acctDb.getDatabase();
std::vector<Account*>::iterator it = db.begin();
cout << "Searching for account " << accountId << endl;
while (it != db.end())
{
if ((*it)->getId() == accountId)
{
cout << "Found account 1" << endl;
// Delete selected account.
delete (*it);
it = db.erase(db.begin());
}
else ++it;
}
}
내가 모든 기능을 테스트 할 수있는 작은 테스트 파일 생성 : 여기
int main()
{
Bank bank;
cout << "Num accounts in bank: " << bank.getNumAccounts() << endl << endl;
cout << "Adding accounts to bank..." << endl;
bank.addChequing(1, 1500.0, "testchq");
bank.addSavings(1, 2000.0, "testsav");
cout << "Num accounts in bank: " << bank.getNumAccounts() << endl;
for (int i = 0; i < bank.getNumAccounts(); ++i)
{
if (bank.getAccount(i + 1) == NULL) cout << "Account is NULL" << endl;
else
{
cout << bank.getAccount(i + 1)->getDetails() << endl;
}
}
cout << endl;
cout << "Deleting account 1..." << endl;
bank.deleteAccount(1);
cout << endl;
cout << "Num accounts in bank: " << bank.getNumAccounts() << endl;
for (int i = 0; i < bank.getNumAccounts(); ++i)
{
if (bank.getAccount(i + 1) == NULL) cout << "Account is NULL" << endl;
else
{
cout << bank.getAccount(i + 1)->getDetails() << endl;
}
}
}
과 내가 파일을 실행 한 후 얻을 출력되는 문제는 다음과 같은 정의 된, 삭제 함께 :
Num accounts in bank: 0
Adding accounts to bank...
Num accounts in bank: 2
Account #1 [C] testchq $1500.000000
Account #2 [S] testsav $2000.000000
Deleting account 1...
Searching for account 1
Found account 1
Num accounts in bank: 2
Account #1 [C] [C] $1500.000000
Account #2 [S] testsav $2000.000000
보시다시피 파생 된 계정 클래스를 올바르게 추가하고 개체 조각을 사용하지 않고 파생 형식을 유지합니다. 삭제 기능에서는 삭제 기능이 삭제할 계정을 찾은 것을 볼 수 있습니다. 문제는 계정 1을 삭제해야하지만 계정 이름을 삭제 한 것입니다 (Account #1 [C] [C] $1500.000000
대 Account #1 [C] testchq $1500.000000
).
여기에서 내가 겪고있는 문제점은 무엇입니까? 나는 또한 이것을하는 나의 방법에 관하여 확신 할 수 없다, 그래서 개선을위한 어떤 제안든지 중대하게 평가 될 것입니다.
미리 감사드립니다.
안녕 @Barry, 답변 해주셔서 감사합니다. 내가해야하는 변경 사항을 명확히하기 위해 Database.h의 getDatabase() const의 서명을'const std :: vector & getDatabase() const; '로 변경해야합니다. 그리고'const vector '를 반복 할 때'const_iterator'를 사용해야합니까? 나는 그것으로 무엇을 전달 하는가?지우기()'함수? 나는 그것을 통과 시키려고 노력했다. ('it = db.erase (it);'). 그러나 그것은 나에게 오류를주고 나는 패스해야 할 것을 확신하지 못한다. 감사! –
user3745117
@ user3745117 아니요, const가 아닌 참조를 반환해야합니다. 수정해야 할 것이기 때문입니다. 그것은 당신의 오래된 서명이'const' 함수라는 것입니다. 여전히'const' 함수를 갖고 싶다면 const ref를 반환하는 별도의 함수 여야합니다. – Barry
명확히 해 주셔서 감사 드리며 완벽하게 작동했습니다! :)이 질문은 원래 질문보다 조금 더 많으므로이 질문에 답할 필요는 없지만, 빠른 누락으로 인해 메모리 누수와 디자인면에서 문제가 있습니까? 다시 한 번 도와 주셔서 감사합니다. – user3745117