`

c++ 学习点滴 list forEach

 
阅读更多
又经过一个周的实战, 我的c++水平已经能够区分 :: . -> 了, 弱爆了的说

下面分享下我的list学习经验, 直接上代码. 由于c++还数量所有 toString 方法有点恶心, 欢迎指导.

/*
 * CharacterColl.h
 *
 *  Created on: 2012-8-14
 *      Author: jie
 */

#ifndef CHARACTERCOLL_H_
#define CHARACTERCOLL_H_

#include <list>
#include "Character.h"

class CharacterColl {
public:
	/**
	 * 删除已死的角色
	 */
	void removeExpired();
	/**
	 * 添加新角色, 添加的时候就排序
	 */
	void addCharacter(Character* c);
	/**
	 *
	 */
	void forEach(bool (*fun)(Character*));

private:
	/**
	 * 所有角色数组
	 */
	std::list<Character*> characters;
	/**
	 * 比较两个角色的层次关系
	 */
	int compair(Character* c1, Character* c2);
	/**
	 * 所有还在这个集合中的元素按照大小排序
	 */
	void sort();
	/**
	 * 删除元素
	 */
	void onDelete(Character* expire);
};

#endif /* CHARACTERCOLL_H_ */


/*
 * Character.cpp
 *
 *  Created on: 2012-8-10
 *      Author: jie
 */

#include "Character.h"
#include <iostream>
#include <stdio.h>

Character::Character(int id, int value) {
	this->value = value;
	this->id = id;
}
Character::~Character() {
	std::cout << "~delete ";
	toString(&std::cout);
	std::cout << "\n";
}
int Character::getName() {
	return value;
}
void Character::toString(std::ostream* cout) {
	char frameName[100] = { 0 };
	sprintf(frameName, "{id:%d, value:%d}", id, value);
	*cout << frameName;
}

/*
 * CharacterColl.h
 *
 *  Created on: 2012-8-14
 *      Author: jie
 */

#ifndef CHARACTERCOLL_H_
#define CHARACTERCOLL_H_

#include <list>
#include "Character.h"

class CharacterColl {
public:
	/**
	 * 删除已死的角色
	 */
	void removeExpired();
	/**
	 * 添加新角色, 添加的时候就排序
	 */
	void addCharacter(Character* c);
	/**
	 *
	 */
	void forEach(bool (*fun)(Character*));

private:
	/**
	 * 所有角色数组
	 */
	std::list<Character*> characters;
	/**
	 * 比较两个角色的层次关系
	 */
	int compair(Character* c1, Character* c2);
	/**
	 * 所有还在这个集合中的元素按照大小排序
	 */
	void sort();
	/**
	 * 删除元素
	 */
	void onDelete(Character* expire);
};

#endif /* CHARACTERCOLL_H_ */

/*
 * CharacterCollColl.cpp
 *
 *  Created on: 2012-8-14
 *      Author: jie
 */
#include "CharacterColl.h"
#include <list>
#include <iostream>
#include "Character.h"

using namespace std;

/**
 * 删除已死的角色
 */
void CharacterColl::removeExpired() {
}

/**
 * 添加新角色, 添加的时候就排序 TODO 可以优化
 */
void CharacterColl::addCharacter(Character* c) {
	list<Character*>::iterator iter = characters.begin();
	while (iter != characters.end()) {
		if (compair(*iter, c) > 0) {
			characters.insert(iter, c);
			return;
		}
		iter++;
	}
	characters.push_back(c);
}

void CharacterColl::onDelete(Character* c) {
	if (c) {
		delete c;
	}
}
/**
 *
 */
void CharacterColl::forEach(bool (*fun)(Character*)) {
	list<Character*>::iterator itor = characters.begin();
	while (itor != characters.end()) {
		if (fun(*itor)) {
			Character* c = *itor;
			itor = characters.erase(itor);
			onDelete(c);
		} else {
			itor++;
		}
	}
}

/**
 * 比较两个角色的层次关系
 */
int CharacterColl::compair(Character* c1, Character* c2) {
	return c1->value - c2->value;
}

/**
 * 所有还在这个集合中的元素按照大小排序
 */
void CharacterColl::sort() {

}



#include <stdio.h>
#include <iostream>
#include "character/CharacterColl.h"

using namespace std;

int charid;

bool printChar(Character* c) {
	c->toString(&cout);
	std::cout << "\n";
	return false;
}
/**
 * 删除奇数
 */
bool removeOdd(Character* c) {
	if (c->value % 2 == 1) {
		return true;
	}
	return false;
}

void addChar(CharacterColl &colls, int i) {
	colls.addCharacter(new Character(charid++, i));
}

int main(void) {
	CharacterColl colls;

	addChar(colls, 10);
	addChar(colls, 14);
	addChar(colls, 10);
	addChar(colls, 13);
	addChar(colls, 20);
	addChar(colls, 17);

	cout << "--------------------- print\n";
	colls.forEach(printChar);

	cout << "--------------------- remove\n";
	colls.forEach(removeOdd);
	colls.forEach(printChar);

	return 0;
}


list 是 std 里面的集合类, 同java的 arraylist 类似, 不过他的iterator对象稍有不同. 上面的代码我实现了这样几个功能
1 插入排入
2 forEach 传递一个 function, function 的返回值可以指导CharacterColl类型是否删除子元素

有几句核心的代码
	list<Character*>::iterator itor = characters.begin();
	while (itor != characters.end()) {
		if (fun(*itor)) {
			Character* c = *itor;
			itor = characters.erase(itor);
			onDelete(c);
		} else {
			itor++;
		}
	}

以上注意itor = characters.erase(itor);删除对象之后指针会自增, 所以无需自己自增.

另一段
void CharacterColl::addCharacter(Character* c) {
	list<Character*>::iterator iter = characters.begin();
	while (iter != characters.end()) {
		if (compair(*iter, c) > 0) {
			characters.insert(iter, c);
			return;
		}
		iter++;
	}
	characters.push_back(c);
}

insert 之后指针指向的是刚增加的元素. 这里和 earse 不同.
分享到:
评论

相关推荐

    foreach的使用

    在C++编程中,`foreach`关键字常用于遍历容器中的元素,它是STL(标准模板库)的一部分,提供了一种简洁的迭代器语法来访问序列容器(如vector、list、deque等)或关联容器(如set、map等)中的元素。在VC6.0环境下...

    你应当如何学习C++

    库开发者可能需要深入研究,以便创建高效的现代C++库,如boost库中的boost::foreach和boost::typeof,这些都展现了对语言细节的深入挖掘。 然而,对于大多数普通程序员来说,关注这些细节并不一定是必要的。真正...

    std::List类的遍历获得元素的操作二法

    ### 方法二:成员函数`foreach`(C++11及更高版本) 从C++11开始,标准库引入了范围基础for循环,这使得遍历容器更加简洁。对于`std::list`,可以这样实现: ```cpp #include #include &lt;list&gt; int main() { std...

    c++学习ppt

    **C++学习PPT概述** C++是一种强大的、通用的编程语言,由Bjarne Stroustrup于1979年在贝尔实验室开发,作为C语言的扩展。它结合了面向对象编程、泛型编程和过程化编程的概念,提供了一种高效、灵活且功能丰富的...

    C#并发实战记录之Parallel.ForEach使用

    C#并发实战记录之Parallel.ForEach使用 本篇文章主要介绍了C#并发实战记录之Parallel.ForEach使用的相关知识点。通过示例代码,详细介绍了Parallel.ForEach...这些知识点对大家学习或者使用C#具有一定的参考学习价值。

    测试mybatis里foreach用法

    在MyBatis中,`&lt;foreach&gt;`标签是一个非常重要的元素,它主要用于动态SQL语句的构建,尤其是在处理集合数据类型如List、Array、Map时。`&lt;foreach&gt;`标签的使用可以极大地提高代码的可读性和可维护性,避免了传统的字符...

    c标签遍历集合嵌套的List集合

    本文详细介绍了如何使用`c:forEach`标签来遍历嵌套的List集合。通过具体的代码示例,我们不仅了解了如何构建这样的集合,还学习了如何在前端页面中优雅地展示这些数据。这种方法广泛应用于实际开发中,有助于提高...

    Mybatis批量foreach merge into的用法

    然后,使用Mybatis的动态SQL语法foreach循环插入,待插入的实体bean的List通过查询数据库dual形成表。foreach的 separator 属性设置每次循环的隔离词为union连接每次形成的表为一个总表。 在总表中,条件匹配时,...

    c#Foreach.rar

    - **集合类**:如`List&lt;T&gt;`、`Dictionary, TValue&gt;`等,`foreach`可以遍历元素或键值对。 ```csharp List&lt;string&gt; fruits = new List&lt;string&gt; { "Apple", "Banana", "Cherry" }; foreach (string fruit in fruits) ...

    C-FOREACH用法

    在这个例子中,`${emps}`是来自上一级`request.setAttribute("emps", list)`的集合,其中`list`是从数据库查询得到的数据。 - `var`: 必需属性,定义了一个局部变量,用于存储每次迭代中的当前元素。在这个例子中,...

    foreach.js低版本IE数组和HTMLCollection元素集合不兼容forEach循环遍历的处理方法

    低版本IE数组和HTMLCollection元素集合不兼容forEach循环遍历的处理方法 原生JavaScript通过name获取dom元素得到的是 HTMLCollection元素集合 要想循环遍历可以用forEach,但是在低于ie9的版本下不兼容 var list...

    c:foreach的各种用法

    &lt;c:forEach var="item" items="${list}"&gt; ${item} &lt;/c:forEach&gt; ``` 在这个例子中,`item` 将代表列表中每个迭代的元素。 ##### 2. `items` `items` 属性用于指定要遍历的数据源,可以是数组或集合类型的数据。 ...

    c#中Foreach详细用法

    C#中Foreach详细用法 Foreach语句是C#语言中的一种循环语句,它提供了一个简洁高效的方式来遍历数组、集合、列表等数据结构。在本文中,我们将详细介绍Foreach语句的用法和优点,并与传统的for循环语句进行比较。 ...

    C#在foreach遍历删除集合中元素的三种实现方法

    在foreach中删除元素时,每一次删除都会导致集合的大小和元素索引值发生变化,从而导致在foreach中删除元素时会抛出异常。 集合已修改;可能无法执行枚举操作。 方法一:采用for循环,并且从尾到头遍历 如果...

    C#foreach用法案例,使用VS2019编写

    对于实现了`IEnumerable`接口的对象,如`List&lt;T&gt;`或`Dictionary, TValue&gt;`,也可以使用`foreach`。以下是一个遍历`List&lt;string&gt;`的例子: ```csharp List&lt;string&gt; fruits = new List() { "Apple", "Banana", ...

    C++参考手册中文版chm以及Boost库中文版chm

    4. **STL(标准模板库)**:讲解容器(如vector、list、set等)、迭代器、算法和函数对象,这些都是C++高效编程的关键工具。 5. **异常处理**:阐述如何在代码中捕获和处理错误,以实现健壮的程序设计。 6. **命名...

    jstl标签 forEach详解

    &lt;c:forEach var="row" items="${list}" varStatus="status"&gt; ${status.index % 2 == 0 ? ' class="even"' : ' class="odd"'}&gt; ${row.column1} ${row.column2} &lt;/c:forEach&gt; ``` 在这个例子中,我们使用 `...

    C++ 。NET基本语法

    在编程领域,C++ .NET 是一种...通过学习这些基本语法和概念,开发者能够有效地利用C++ .NET进行.NET平台的开发,同时充分利用现有的C++代码库。在实践中,理解这些特性对于顺利地将C++项目迁移到.NET环境至关重要。

    c:forEach标签的使用祥解

    &lt;% List&lt;String&gt; names = Arrays.asList("Alice", "Bob", "Charlie"); request.setAttribute("names", names); %&gt; ... &lt;c:forEach items="${names}" var="name"&gt; 用户名: ${name} &lt;/c:forEach&gt; ``` 3. 遍历...

Global site tag (gtag.js) - Google Analytics