Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;删除for循环中的列表成员_C++_For Loop - Fatal编程技术网

C++ C++;删除for循环中的列表成员

C++ C++;删除for循环中的列表成员,c++,for-loop,C++,For Loop,假设您有一个have类Base,它有两个函数foo()和goo(),还有一个bool boolean,当创建一个Base对象时,它被赋值为0或1。那么我们有以下几点: //declaring a list std::list<Base*> base; //creating 10 objects of Base and storing on the list for (int i = 0; i < 10; i++) { Base *b = new Base();

假设您有一个have类Base,它有两个函数foo()和goo(),还有一个bool boolean,当创建一个Base对象时,它被赋值为0或1。那么我们有以下几点:

//declaring a list
std::list<Base*> base;
//creating 10 objects of Base and storing on the list
for (int i = 0; i < 10; i++)
{
    Base *b = new Base();
    base.push_back(b);
}
for (auto i = base.begin(); i != base.end();)
{
    Base *e = *i;

    e->foo();
    e->goo();
    if (e->boolean == false)
    {
        i = base.erase(i);
        delete e;
    }
    else
        i++;
}
//声明一个列表
std::列表库;
//创建10个基本对象并存储在列表中
对于(int i=0;i<10;i++)
{
Base*b=新的Base();
基地。推回(b);
}
for(自动i=base.begin();i!=base.end();)
{
基数*e=*i;
e->foo();
e->goo();
如果(e->boolean==false)
{
i=基。擦除(i);
删除e;
}
其他的
i++;
}
第一个问题:程序员为什么省略for循环中的第三个参数?它是隐式的i++吗? 第二个问题:请告诉我什么时候使用擦除和/或删除,或者两者都使用,以及为什么在这段代码中需要这样做。还向我解释Base*e=*i的需要;而不是只调用i->foo();i->goo()直接输入。非常感谢:)

第一个问题 注
i=base.erase(i)。擦除后,
i
无效,它指向的列表项不存在,因此
erase
返回被擦除项后的下一项,以允许您继续浏览列表。因为
i
已经在引用本应是
i++
的内容,在
for
循环中向其添加额外的
i++
将跳过列表中的一项

如果未擦除任何项,则在else情况下处理常规的
i++

请看一看,寻找一种更好的方法来实现这一点

第二个问题
i
是指向
Base
1的指针的迭代器,因此
i->foo()
将尝试在指针上调用
foo
,而指针没有
foo
。与其可怜
foo
,不如先取消对迭代器的引用,然后再取消对指针的引用

你不能
i->->->foo(),但您可以
(*i)->foo()
(*i)
取消对迭代器的引用,并为
->foo()
部分提供指针

Base *e = *i; 
缓存取消引用的迭代器,因此

e->foo();

(*i)->foo();
也许这会使代码更容易阅读。也许它有一个小的性能优势。这取决于您必须
(*i)
的数量以及您给出的
e
名称的描述性
e
作为变量名很糟糕,因为你不得不问这个问题。一个好的变量名会告诉您发生了什么

顺便说一句,你几乎从来都不想这么做。让库容器包含对象的实例,而不是指针,这样它们就可以为您管理所有内存。使内存管理更容易是它们设计的一个重要方面


然而在本例中,名称
Base
表明多态性正在发挥作用。多态对象列表大概是您唯一需要指针容器的时候。但是,请查看以管理任何动态分配的多态对象的生命周期。

如果省略了“for”的增量表达式,则不会执行任何操作

for(init ; test; increment)
身体

始终相当于:

{
  init ;
  while(test)
    body
}

周围括号构成C++变量的行为,其初始化变量仅限于for语句< /p>注释>代码> i=BASE。擦除(i);<代码><代码>擦除

返回已擦除项后的下一项。在上面添加一个额外的++会很糟糕。这回答了我的第一个问题,谢谢。第二个呢?@Powereleven:因为当你删除指针时,它在
列表中已经不存在了;如果您没有保存副本,您将泄漏内存,无法正确清理它(这就是为什么真正的代码倾向于使用
std::shared_ptr
std::unique_ptr
,因此它不必手动管理内存)。请注意,使用“for”这三个部分都是可选的。for(;;)是完全合法的,相当于for(;1;)使用
std::list base不需要手动删除。您猜对了:P Base有一个虚拟函数和几个重写它的派生类。