随笔 - 96  文章 - 255  trackbacks - 0
<2010年6月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

E-mail:zbln426@163.com QQ:85132383 长期寻找对战略游戏感兴趣的合作伙伴。

常用链接

留言簿(21)

随笔分类

随笔档案

SDL相关网站

我的个人网页

我的小游戏

资源下载

搜索

  •  

积分与排名

  • 积分 - 488801
  • 排名 - 37

最新评论

阅读排行榜

评论排行榜

        这段时间在复习C++基础,算法与数据结构,以及学习STL。所以,SDL的教程更新会慢些。因为我还是以自己的项目为核心进行学习的,所以基础知识和游戏设计涉及到图形,控制和多线程的内容学习,应该是会有些交叉的。
        发现这个问题,是因为一直以来思考的一个算法——关于“集合”的实现。这个集合就是数学中的集合,与计算机中数列一个最大的不同在于,集合的元素是互异的。因为这两天在熟悉vector,所以觉得用vector实现集合再合适不过了。STL确实是很好很强大的体系,无论是内存管理,还是链表的实现,让我们可以省很多心。其实关于为什么要实现集合,也是因为我在计划实现类似英雄无敌战场计算移动的一系列算法中,很多地方会用到集合的概念,甚至包括并集和差集等等。也许我想到的算法是很笨拙的,但是在我还没有完全阅读相关的已有代码之前,觉得完全凭自己的认识,实现这些算法还是很有意义的,所以,从学习C++的第一天开始,我就在试图找到解决这些问题的方法,而现在,越来越清晰了,呵呵。
        我的思路很直接也很简单,就是把一个数组中的元素往一个新的数组中填,新填充的元素会遍历新数组中已有的元素,如果与之互异,则填入(push),否则就跳到下一个。以上就已经确立了成员数据(私有)和构造函数。因为我们需要“集合化”了的数组是可以被外部访问的,所以一个最简单的方法就是把成员数据公有——这确实是很简单,而且这样就不会出现今天我们要讨论的问题了;另外一个笨办法是用一个公有方法,返回成员数据的值——我就是这么做的,因为这貌似更符合OOP的“数据隐藏”的精神-_-!!!。很快可以写出头文件:
#ifndef AGGREGATE_H_
#define AGGREGATE_H_

#include 
<iostream>
#include 
<vector>
#include 
<algorithm>

class Aggregate
{
private:
    std::vector
<int> agg;
public:
    Aggregate(std::vector
<int>& temp);
    
const std::vector<int> getAgg() const;
};

#endif
请注意那个红色的const,其实我想说的是,第一次写这个程序的时候,我并没有这个const。一直以来,除了在重载“=”的时候我大概清楚修饰返回值const的作用是可以避免让返回值做左值,其他时候还真不太明白这个const的作用,只是本着C++的精神——能const就const吧-_-!!!。实现文件:
#include "aggregate.h"

Aggregate::Aggregate(std::vector
<int>& temp)
{
    
for ( std::vector<int>::iterator pTemp = temp.begin(); pTemp != temp.end(); pTemp++ ) {
        
bool findSame = false;
        
for ( std::vector<int>::iterator pAgg = agg.begin(); pAgg != agg.end(); pAgg++ )
            
if ( *pTemp == *pAgg )
                findSame 
= true;
        
if ( findSame == false )
            agg.push_back(
*pTemp);
    }
}

const std::vector<int> Aggregate::getAgg() const
{
    
return agg;
}
一切都很完美,不是吗?顺手就继续写出一个测试用的程序:
#include "aggregate.h"

void show(int& i);

int main(int argc, char* argv[])
{
    std::vector<int> tempArray;
    int temp;
    bool goon = true;

    while ( goon == true ) {
        std::cout << "#" << tempArray.size()+1 << "= ";
        std::cin >> temp;
        if ( temp == -1 ) {
            goon = false;
            continue;
        }
        tempArray.push_back(temp);
    }

    std::cout << "You've entered " << tempArray.size() << " numbers." << std::endl;

    for_each(tempArray.begin(), tempArray.end(), show);

    std::cout << "----------------------------\n" << "Now, to be aggregate\n";

    Aggregate tempAgg (tempArray);
    std::cout << "There are " << tempAgg.getAgg().size() << " different numbers.\n";
    for_each(tempAgg.getAgg().begin(), tempAgg.getAgg().end(), show);


    return 0;
}

void show(int& i)
{
    std::cout << i << std::endl;
}
很不幸,编译正常的通过了(注意,没有红色的const的时候)。
但是,运行时出现了错误。
运行时错误是件令人很郁闷的事情,因为这意味着编译器不会帮你找到出错的地方。
幸运的是,直觉让我觉得类似tempAgg.getAgg().begin()的用法有问题,所以,我改成了:(紫色那部分代码)
    std::cout << "----------------------------\n" << "Now, to be aggregate\n";

    Aggregate tempAgg (tempArray);
    std::vector
<int> tempAggArray = tempAgg.getAgg();
    std::cout 
<< "There are " << tempAggArray.size() << " different numbers.\n";
    for_each(tempAggArray.begin(), tempAggArray.end(), show);
这样,问题是解决了。但是我们回头分析一下,刚才的问题到底出在什么地方呢?
其实,如果我们加上红色的const,使用原来的代码进行编译的时候,编译器是可以指出我们的错误的,确实是tempAgg.getAgg().begin()的用法出了问题。具体的原因包含在<algorithm>里面,我没有仔细去分析,但是我们至少明白了,方法begin()会试图修改其对象的返回值!
        让错误被发现在编译阶段,远远好于被发现在运行时阶段。我想,这就是C++中const最大的作用。所以,总结起来还是C++的一句话,能const,就const吧。:)
posted on 2008-03-13 13:30 lf426 阅读(911) 评论(3)  编辑 收藏 引用 所属分类: 语言基础、数据结构与算法

FeedBack:
# re: 从“集合”实例分析修饰函数返回值的const作用 2008-03-14 21:30 fcc-casia
"就是把一个数组中的元素往一个新的数组中填,新填充的元素会遍历新数组中已有的元素,如果与之互异,则填入(push),否则就跳到下一个。"像完成这种功能为何不用map?平衡二叉树的效率应该比线性列表高吧?  回复  更多评论
  
# re: 从“集合”实例分析修饰函数返回值的const作用[未登录] 2008-03-15 00:21 lf426
呵呵,本人水平有限哈。数据结构和算法还在学习中,STL的那些容器还没有完全体会在不同情况下使用的优势和劣势。  回复  更多评论
  
# re: 从“集合”实例分析修饰函数返回值的const作用[未登录] 2009-01-01 19:47 Felicia
C++的STL里面已经有集合了
#include <set>  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理