int main(){
vector<Customer*> newcustomer;
newcustomer.push_back(new Customer("III", 123333, 555));
newcustomer.push_back(new Customer("LOL", 122222, 444));
newcustomer.push_back(new Customer("PPL", 121111, 333));
for (int i = 0; i < 3; i++){
cout << newcustomer[i]->getName() << endl;
cout << newcustomer[i]->getPhone() << endl;
cout << newcustomer[i]->getID() << endl;
cout << endl;
}
system("pause");
return 0;
}
所以我创建了一个名为customer的类,你可以插入新客户,getName返回名称,getPhone返回电话号码,GetID返回ID,现在我想从该向量中删除所有内容,不确定如何操作。
答案 0 :(得分:5)
要清除矢量中的所有元素,您只需使用即可
myvector.erase (myvector.begin(),myvector.end());
或myvector.clear()
。
但是这里的问题不仅仅是从向量中删除元素,还要删除在堆上分配的内存。以下是我的解决方案。
int main(){
vector<Customer*> newcustomer;
newcustomer.push_back(new Customer("III", 123333, 555));
newcustomer.push_back(new Customer("LOL", 122222, 444));
newcustomer.push_back(new Customer("PPL", 121111, 333));
for (int i = 0; i < 3; i++){
cout << newcustomer[i]->getName() << endl;
cout << newcustomer[i]->getPhone() << endl;
cout << newcustomer[i]->getID() << endl;
cout << endl;
}
while(!newcustomer.empty())
{
Customer *cust = newcustomer.front();
newcustomer.erase(newcustomer.begin());
delete cust;
}
system("pause");
return 0;
}
答案 1 :(得分:3)
如果您只想删除矢量中的所有内容,请使用: http://www.cplusplus.com/reference/vector/vector/erase/
它是矢量的擦除功能
// erase the first 3 elements:
newcustomer.erase (newcustomer.begin(),newcustomer.begin()+3);
答案 2 :(得分:1)
你可能不应该使用vector<Customer*>
;对于大多数应用程序vector<Customer>
会更好,对于大多数剩余的应用程序,vector<unique_ptr<Customer>>
(或有时vector<shared_ptr<Customer>>
)会更好。
但要回答你的问题,要对向量的每个元素做一些事情,你要使用循环:
for(auto &x: newcustomer) {
delete x;
// x = nullptr; // optional: don't leave a dangling pointer
}
答案 3 :(得分:0)
在函数结束时,newcustomer
将超出范围,并且将调用析构函数。 std::vector
的析构函数会删除向量的内容,并在适用时调用析构函数。
您可以通过调用clear
成员函数来提前调用此行为:
#include <iostream>
#include <vector>
#include <iostream>
#include <vector>
struct S {
S(const char* v_) : m_v(v_) {}
~S() {
std::cout << "destructing ~S(" << m_v << ")\n";
}
const char* m_v;
};
int main()
{
std::vector<S> v;
v.emplace_back("hello");
v.clear();
v.emplace_back("fin");
}
您还可以使用迭代器删除特定范围的元素:
v.erase(v.begin(), v.end());
但是:应该注意的是,您正在使用指针,并且从向量中删除指针并不会释放它们指向的实例:
#include <iostream>
#include <vector>
struct S {
S(const char* v_) : m_v(v_) {}
~S() {
std::cout << "destructing ~S(" << m_v << ")\n";
}
const char* m_v;
};
int main()
{
std::vector<S*> v;
v.push_back(new S("hello"));
v.clear();
v.push_back(new S("fin"));
}
http://ideone.com/QZLRXv - 没有输出,因为没有任何内容被释放。
您使用new
分配的内存必须为delete
或delete[]
d。
你可以自己做:
for (Customer* ptr : newcustomer) {
delete ptr;
}
newcustomer.clear();
或者您可以使用其中一个标准指针管理类。
std::vector<std::unique_ptr<Customer>> newcustomer;
newcustomer.emplace_back(std::make_unique<Customer>(...));
完整代码:
#include <iostream>
#include <vector>
#include <memory>
struct Customer
{
Customer(const char* name_, int i_, int j_)
: m_name(name_), m_i(i_), m_j(j_) {}
~Customer()
{
std::cout << "~Customer(" << m_name << ")\n";
}
const char* m_name;
int m_i, m_j;
const char* getName() const noexcept { return m_name; }
int getPhone() const noexcept { return m_i; }
int getID() const noexcept { return m_j; }
};
int main()
{
std::vector<std::unique_ptr<Customer>> customers;
customers.emplace_back(std::make_unique<Customer>("Andy", 123, 111));
customers.emplace_back(std::make_unique<Customer>("Bob", 124, 222));
customers.emplace_back(std::make_unique<Customer>("Chris", 125, 333));
for (auto& ptr : customers) {
std::cout << ptr->getName() << "\n";
std::cout << ptr->getPhone() << "\n";
std::cout << ptr->getID() << "\n";
std::cout << "\n";
}
// remove the first customer
std::cout << "pop:\n";
customers.erase(customers.begin());
// remove the rest
std::cout << "clear:\n";
customers.clear();
}
答案 4 :(得分:0)
如上所述,newcustomer.clear()将清空向量,但它不会处理指针。 HadeS在他或她的解决方案中关心这个问题。以下是解决问题的更多方法。
与某些语言不同,在C ++中,不必使用new
制作指针。此方法丢弃指针并直接将Customer存储在向量中。这通常是最安全的解决方案,因为您必须努力使解决方案出错。
int main()
{
vector<Customer> newcustomer;
newcustomer.push_back(Customer("III", 123333, 555));
newcustomer.push_back(Customer("LOL", 122222, 444));
newcustomer.push_back(Customer("PPL", 121111, 333));
// do stuff
newcustomer.clear();
return 0;
}
这有点笨重。您创建一个临时Customer(调用构造函数)并将其复制到向量中(调用复制构造函数)。使用适当的调试语句在客户构造函数和析构函数中,您最终得到如下所示的垃圾:
create III
copy III
destroy III
create LOL
copy LOL
copy III
destroy III
destroy LOL
create PPL
copy PPL
copy III
copy LOL
destroy III
destroy LOL
destroy PPL
Use III
Use LOL
Use PPL
destroy III
destroy LOL
destroy PPL
3创造,6个副本,9个破坏。
如果Customer由指针或复杂的自定义数据类型组成,那么您可能需要定义复制构造函数以使其工作。 See the Rule Of Three
C ++ 11的方法不那么繁琐:
int main()
{
vector<Customer> newcustomer;
newcustomer.emplace_back("III", 123333, 555);
newcustomer.emplace_back("LOL", 122222, 444);
newcustomer.emplace_back("PPL", 121111, 333);
// do stuff
newcustomer.clear();
return 0;
}
摆脱第一个版本完成的一些工作。输出如下:
create III
create LOL
copy III
destroy III
create PPL
copy III
copy LOL
destroy III
destroy LOL
Use III
Use LOL
Use PPL
destroy III
destroy LOL
destroy PPL
3创造,3个副本,6个破坏。
如果Customer有一个移动构造函数,则输出如下所示:
create III
create LOL
move III
destroy
create PPL
move III
move LOL
destroy
destroy
Use III
Use LOL
Use PPL
destroy III
destroy LOL
destroy PPL
3创造,3次移动,6次摧毁。
如果客户花费很长时间来复制或使用大量内存,那么实施移动构造函数的时间是相当的,即使是临时也不会重复。虽然如果您使用大量内存,通常副本需要很长时间。
重要提示:看看有哪些destroy
不知道他们是谁?这是因为移动构造函数从字面上将数据从源移动到目标。来源不再有任何数据。它取决于移动构造函数,不会让源处于这样的状态:如果在移动后使用源,则源将显示未定义的行为。欢迎来到the Rule of 5。
如果由于某种原因你必须有指针,将吸盘包装在智能指针中可以使你的生活在内存管理方面更容易。例如:
int main()
{
vector<unique_ptr<Customer>> newcustomer;
newcustomer.emplace_back(new Customer("III", 123333, 555));
newcustomer.emplace_back(new Customer("LOL", 122222, 444));
newcustomer.emplace_back(new Customer("PPL", 121111, 333));
// do stuff
newcustomer.clear();
return 0;
}
这个人的输出看起来像是蜜蜂的膝盖:
create III
create LOL
create PPL
Use III
Use LOL
Use PPL
destroy III
destroy LOL
destroy PPL
但是没有显示的是,unique_ptrs的创建,移动和销毁速度与上一个示例中的客户相同。根据客户移动构造函数的成本,您可能会或可能不会使用unique_ptr节省任何时间或精力。