免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: catmonkey_lee
打印 上一主题 下一主题

[C++] stl容器中保存string是不是好的做法 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2008-04-23 18:20 |只看该作者
原帖由 catmonkey_lee 于 2008-4-23 16:32 发表
但是用sizeof来看string对象的话,占用内存为4字节,和char *一样阿?
而且如果string 的拷贝构造实现基础只是引用计数加一的话,那么也不用完全拷贝字符串阿?

所以我还是觉得string可以  几乎   完全替代char  ...

各种库的实现方式并不相同,你可以看看Effective STL中Item 15
如果你有兴趣,可以进一步可以看看这篇文章Optimizations That Aren't (In a Multithreaded World)

论坛徽章:
0
12 [报告]
发表于 2008-05-02 03:06 |只看该作者

回复 #1 catmonkey_lee 的帖子

为了避免各种麻烦,容器里建议只用来容纳对象,对象才是自我完整的,自己对自己负责,否则在容器中采用一些原始的类型的话,麻烦会经常光顾的。

论坛徽章:
0
13 [报告]
发表于 2008-05-02 09:45 |只看该作者

C++是不完美的,很多事情要自己处理。我不喜欢用模板。请注意这里的hold

class CObject : public virtual IObject
{
private:
    int objref;

protected:
    CObject() :
        objref(0)
    {
    }

public:
    virtual bool equals(const IObject *o) const
    {
        if (this == o)
            return true;

        return false;
    }

    virtual int hold(int refs)
    {
        refs += objref;

        if (refs < 1)
        {
            destroy();
            return refs;
        }

        return objref = refs;
    }

    virtual void destroy()
    {
        delete this;
    }

public:
    virtual ~CObject()
    {
    }
};




class CMap : public CObject, public virtual IMap
{
private:
&nbsp;&nbsp;&nbsp;&nbsp;IArray *array;

public:
&nbsp;&nbsp;&nbsp;&nbsp;virtual void clear()
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array->clear();
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;virtual void add(IObject *o)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IPair *p = dynamic_cast<IPair *>(o);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (0 == p)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new CException(new CString("add Pair only"));

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array->add(o);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;virtual void remove(IObject *o)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array->remove(o);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;virtual int getCount() const
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return array->getCount();
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;virtual int getSize() const
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return array->getSize();
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;virtual void first()
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array->first();
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;virtual bool hasMore()
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return array->hasMore();
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;virtual IObject * next()
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return array->next();
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;virtual void set(IObject *key, IObject *value)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (array->getCount() < 1)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array->add(new CPair(key, value));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IPair *p;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IObject *k;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int total = array->getSize();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i < total; i++)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p = dynamic_cast<IPair *>(array->get(i));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (0 == p)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;continue;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;k = p->getKey();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (0 == p)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;continue;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (k->equals(key))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array->set(i, new CPair(key, value));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;virtual IObject * get(IObject *key)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IPair *p;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IObject *k;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array->first();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while (array->hasMore())
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p = dynamic_cast<IPair *>(array->next());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (0 == p)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;continue;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;k = p->getKey();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (0 == p)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;continue;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (k->equals(key))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return p->getValue();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;CMap(IArray *arr)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array = arr;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (0 == array)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array = new CArray();
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;~CMap()
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array->destroy();
&nbsp;&nbsp;&nbsp;&nbsp;}


[ 本帖最后由 yuanchengjun 于 2008-5-2 09:49 编辑 ]

论坛徽章:
0
14 [报告]
发表于 2008-05-02 21:48 |只看该作者
我的看法是 速度不是最重要的。 正确是第一的。

放string 会慢。 但是放了char * 很可能出错误的结果。 你会怎么选?

先做出正确的, 再做出高效的, 最后是优雅的。 这是我的一贯思想。

论坛徽章:
0
15 [报告]
发表于 2008-05-03 02:21 |只看该作者
原帖由 mars_man 于 2008-5-2 03:06 发表
为了避免各种麻烦,容器里建议只用来容纳对象,对象才是自我完整的,自己对自己负责,否则在容器中采用一些原始的类型的话,麻烦会经常光顾的。



我们的做法恰好相反,我们从不在容器里面放对象。我们只在容器里面放整数和指针。

首先,容器不适合放自定义对象(因为拷贝构造之类的麻烦事)。
其次,容器在放string之类的对象的话,90%的程序员会搞不清楚内存问题。

所以,我们从不偷懒,容器里面我们只存放基本数据类型。

论坛徽章:
0
16 [报告]
发表于 2008-05-03 12:59 |只看该作者
我们的做法恰好相反,我们从不在容器里面放对象。我们只在容器里面放整数和指针。


多线程中间,当你需要删除掉容器里面的这个对象, 你需要保证没有线程正在使用这个对象。
这个是非常困难的,一件事情。首先,你需要锁定这个容器, 然后 你需要保证,没有人在使用这个对象。 一点点问题 就可能造成,你删除了一个 别的线程正在使用的一个对象。

论坛徽章:
0
17 [报告]
发表于 2008-05-03 13:28 |只看该作者

回复 #16 im2web 的帖子

"多线程中间,当你需要删除掉容器里面的这个对象, 你需要保证没有线程正在使用这个对象"

首先,会出现这种情况,说明这个程序的架构设计有问题。
其次,真有这种情况,也可以用删除队列来解决(我们维护老程序的时候遇到过这样的问题)。
第三,在容器里面放对象,完全不能解决对象的跨线程安全问题。除了string这样少数的独特的对象,大多数对象仍然需要你自己维护线程安全性。
第四,不能因噎废食,为了配合不好的设计而放弃良好的设计。

[ 本帖最后由 wwwsq 于 2008-5-3 13:32 编辑 ]

论坛徽章:
0
18 [报告]
发表于 2008-05-03 19:22 |只看该作者
原帖由 wwwsq 于 2008-5-3 13:28 发表
"多线程中间,当你需要删除掉容器里面的这个对象, 你需要保证没有线程正在使用这个对象"

首先,会出现这种情况,说明这个程序的架构设计有问题。
其次,真有这种情况,也可以用删除队列来解决(我们维护老 ...


很多时候不合理的设计是因为现实环境的要求。删除队列也不能完全解决这个问题。 需要用引用数记录 + 小范围锁定的问题来解决。
非常繁琐。 但是其实这样做可以非常高的提高多线程的效率。  简单的算法 很简单也是正确的。但那是单线程。如果是多线程,很多设计反而会非常的古怪,而繁琐。 但是这的确是高效的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP