首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

STL list容器的引用语议讨论,该怎么解决

2012-03-12 
STL list容器的引用语议讨论前提:list中装载的引用语义(对象指针),非值语义,这里不是讨论值语义与引用语义

STL list容器的引用语议讨论
前提:list中装载的引用语义(对象指针),非值语义,这里不是讨论值语义与引用语义。

请高手指点,下面的代码有没有内存问题。代码在BCB6.0中编译通过。

//---------------------------------------

#pragma   hdrstop

//---------------------------------------

#include   <list.h>
#include   <iostream.h>
#include   <algorithm.h>
#pragma   argsused

const   MAX_BUFFER_1   =   256;
const   MAX_BUFFER_2   =   65536;

class   _Parameter
{
private:
        char   *_name;
public:
        char*   __fastcall   name(void)   {   return   _name;   }

        __fastcall   _Parameter(char*   value)
        {
                _name   =   NULL;

                _name   =   new   char[strlen(value)   +   1];
                strcpy(_name,   value);
        }

        __fastcall   ~_Parameter()
        {
                std::cout   < <   "销毁对象: "   < <   _name   < <   std::endl;
               
                //释放对象资料
                if   (_name   !=   NULL)
                        delete[]   _name;

        }
};

template   <class   t>       //查找函数
class   findvalue
{
private:
        char   *_name;
public:
        findvalue(char   *name)   :   _name(name)   {   }
        bool   operator()(const   t*   ptr)   const
        {
                if   (strcmp(ptr-> name(),   _name)   ==   0)
                        return   true;
                else
                        return   false;
        }
};

template   <class   t>   //查找符合条件的容器项,并删除该项中的内容--对象指针。
class   removevalue
{
private:
        char   *_name;
public:
        removevalue(char   *name)   :   _name(name)   {   }
        bool   operator()(const   t*   ptr)   const
        {
                if   (strcmp(ptr-> name(),   _name)   ==   0)
                {
                        delete   ptr;     //在此外删除对象,可行吗?
                        return   true;


                }
                else
                        return   false;
        }
};

template   <class   t>     //删除所有的指针操作。
struct   deletevalue
{
        void   operator()(t*   ptr)   {   delete   ptr;   }
};

int   main(int   argc,   char*   argv[])
{

        list <_Parameter*> ::iterator   iparam;
        list <_Parameter*>   factory;

        char   name[50];
        _Parameter*   parameter;

        memset(name,   '\0 ',   50);
        strcpy(name,   "China ");
        parameter   =   new   _Parameter(name);
        factory.push_back(parameter);

        memset(name,   '\0 ',   50);
        strcpy(name,   "British ");
        parameter   =   new   _Parameter(name);
        factory.push_back(parameter);

        memset(name,   '\0 ',   50);
        strcpy(name,   "America ");
        parameter   =   new   _Parameter(name);
        factory.push_back(parameter);

        //查找对象。
        iparam   =   find_if(factory.begin(),
                factory.end(),
                findvalue <_Parameter> ( "British "));
        if   (iparam   !=   factory.end())
        {
                cout   < <   "找到对象: "   < <
                        (static_cast <_Parameter*> (*iparam))-> name()   < <   endl;
                cout   < <   "对象地址: "   < <
                        reinterpret_cast <int> (*iparam)   < <   endl;

        }

        //删除对象。
        iparam   =   remove_if(factory.begin(),
                factory.end(),
                removevalue <_Parameter> ( "British "));
        factory.erase(iparam);

        iparam   =   find_if(factory.begin(),
                factory.end(),
                findvalue <_Parameter> ( "British "));
        if   (iparam   ==   factory.end())
        {
                cout   < <   endl   < <   "British对象已经被删除 "   < <   endl   < <   endl;


        }

        //删除所有对象。
        for_each(factory.begin(),
                factory.end(),
                deletevalue <_Parameter> ());
        factory.clear();


        return   0;
}
//---------------------------------------


[解决办法]
这个,我建议你不要费力自己搞了。
stl容器都有多种删除数据的方法,比如clear。。。
你还是要么使用list <boost::shared_ptr <T *> >
要么直接使用boost::ptr_list <T>
[解决办法]
有很大问题。参考《Effective》
条款33:提防在指针的容器上使用类似remove的算法
条款39:用纯函数做判断式
条款44:尽量用成员函数代替同名的算法

风格上的问题就更大了。
[解决办法]
有些问题:

1.对一个const t* 执行非const操作。

bool findvalue::operator()(const t* ptr) const
{
if (strcmp(ptr-> name(), _name) == 0) // 此处_Parameter::name是非const操作
return true;
else
return false;
}

bool removevalue::operator()(const t* ptr) const
{
if (strcmp(ptr-> name(), _name) == 0)
{
delete ptr; // 此处_Parameter::~Parameter是非const操作
// 并不能对const t*做delete
return true;
}
else
return false;
}

2. remove_if的返回值是remove操作完成后的factory.end(),
所以 factory.erase(iparam); 不必要。

将char* __fastcall _Parameter::name(void)加上const,
并将bool removevalue::operator()(const t* ptr) const 的参数改为t* ptr
LZ的用法应该可行.



[解决办法]
厄 。。。。
[解决办法]

[解决办法]
shared_ptr的问题是1直到最后一个指针delete,它才真的释放内存
2很容易发生循环引用。即使借助weaked_ptr,可以消除循环引用,可是加大了设计难度。
所以,看起来还是boost::ptr_container比较好些。
[解决办法]
很高深, 学习.
楼主的代码我没看, 写的好不好先不说, 能有精神去写就值得表扬.

热点排行