template< class C > class TComList : public std::list< C > { public: typedef typename std::list<C>::iterator TComIterator; TComList& operator += ( const TComList& rcTComList) { if( ! rcTComList.empty() ) { insert( this->end(), rcTComList.begin(), rcTComList.end()); } return *this; } // leszek C popBack() { C cT = this->back(); this->pop_back(); return cT; } C popFront() { C cT = this->front(); this->pop_front(); return cT; } Void pushBack( const C& rcT ) { /*assert( sizeof(C) == 4);*/ if( rcT != NULL ) { this->push_back( rcT); } } Void pushFront( const C& rcT ) { /*assert( sizeof(C) == 4);*/ if( rcT != NULL ) { this->push_front( rcT); } } TComIterator find( const C& rcT ) // leszek { return find( this->begin(), this->end(), rcT ); } };
list就是数据结构中的双向链表(根据sgi stl源代码),因此它的内存空间可以是不连续的,通过指针来进行数据的访问。
class C 的取值有TComList<TComPicYuv*> , TComList<TComPic*> 。及TComList<TComPic*>::iterator,TComList<TComPicYuv*>::iterator。
TComList<TComPicYuv*> m_cListPicYuvRec; ///< list of reconstruction YUV files
TComList<TComPic*> m_cListPic; ///< dynamic list of pictures
m_cListPic 用到的函数有size(), begin(),end(),erase(),insert()
m_cListPicYuvRec size(), begin(),end()
list<C>的结点结构,是一个环状双向链表。转换成C后,ilist是一个空结点(head),只需要这样衣个环中的空结点便可表示出整个
链表。对于迭代器类型,转换为TComList_pTComPicYuv*结点类型,指向某个结点,而迭代器类型不但知道了结点的位置,还直接
指向了结点的数据(data)。
typedef struct _TComList_pTComPicYuv { struct _TComList_pTComPicYuv* next; struct _TComList_pTComPicYuv* prev; TComPicYuv* data; }TComList_pTComPicYuv;
一个根据stl_list.h中的create_node函数改为对应的C来实现:
TComList_pTComPicYuv* TComList_pTComPicYuv_create_node( TComPicYuv* x) { TComList_pTComPicYuv* this_ptr; /* Allocate memory of struct size. */ this_ptr = (TComList_pTComPicYuv *) malloc(sizeof(TComList_pTComPicYuv)); if(this_ptr == NULL) { printf("Alloc memory failed!\n"); exit(0); } else { this_ptr->data = x; this_ptr->prev = NULL; this_ptr->next = NULL; } return this_ptr; }
problem:
1.error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int d:\hm\source\lib\tlibcommon\tcompicsym_c.h 72
#include "TComPic_C.h" 在有些文件中不能被包含,一包含就出现很多错误。由于TComPic 类的成员关系中存在一个循环结构,需要TComPic 声明的地方,只使用struct TComPic; 来声明TComPic即可,而不使用包含"TComPic_C.h" 的方式。
2.
Void TComSlice::sortPicList (TComList<TComPic*>& rcListPic) { ... iterPicExtract_1 = iterPicExtract; iterPicExtract_1++; // swap iterPicExtract and iterPicInsert, iterPicExtract = curr. / iterPicInsert = insertion position rcListPic.insert (iterPicInsert, iterPicExtract, iterPicExtract_1); rcListPic.erase (iterPicExtract); }
改写为:
{iterPicExtract_1 = iterPicExtract; iterPicExtract_1 =iterPicExtract_1->next; // swap iterPicExtract and iterPicInsert, iterPicExtract = curr. / iterPicInsert = insertion position //for ( ; iterPicExtract != iterPicExtract_1; iterPicExtract=iterPicExtract->next) TComList_pTComPic_insert( iterPicInsert,iterPicExtract->data); //iterPicExtract=iterPicExtract->next; TComList_pTComPic_erase(rcListPic,iterPicExtract); }
该函数中这段语句的改写,该段语句实际上是在iterPicInsert之前再插入一个iterPicExtract指向的元素,然后再erase 原来的iterPicExtract ,即实现了iterPicExtract and iterPicInsert 的调换。
insert函数的调用为(文件<list>):
template<class _Iter>
void insert(const_iterator _Where, _Iter _First, _Iter _Last)
{ // insert [_First, _Last) at _Where _Insert(_Where, _First, _Last, _Iter_cat(_First));//_Iter_cat(_First)返回迭代器类型,决定重载调用哪个函数
}
template<class _Iter>
void _Insert(const_iterator _Where,
_Iter _First, _Iter _Last, forward_iterator_tag)
{ // insert [_First, _Last) at _Where, forward iterators
_DEBUG_RANGE(_First, _Last);
_Iter _Next = _First;
_TRY_BEGIN
for (; _First != _Last; ++_First)//展开实际上是这两句,_First = iterPicExtract,_Last=iterPicExtract_1
_Insert(_Where, *_First);
_CATCH_ALL
for (; _Next != _First; ++_Next)
{ // undo inserts
const_iterator _Before = _Where;
erase(--_Before);
}
_RERAISE;
_CATCH_END
}
由于iterator 的范围[begin,end)是一个前闭后开的区间,改成C后head->next等于begin,head等于end,但是在判断是否达到末尾时
还会有与迭代器的判断有差别。
// find current position
TComList<TComPic*>::iterator iterPic = rcListPic.begin();
TComPic* pcRefPic = NULL;
TComPic* pcPic = *(iterPic);
while ( (TComPic_getPOC(pcPic) != (Int)uiPOCCurr) && (iterPic != rcListPic.end()) )
{
iterPic++;
pcPic = *(iterPic);//
} 改写为:
// find current position
TComList_pTComPic* iterPic = rcListPic->next;
TComPic* pcRefPic = NULL;
TComPic* pcPic = iterPic->data;
while ( (TComPic_getPOC(pcPic) != (Int)uiPOCCurr) && (iterPic != rcListPic) )
{
iterPic=iterPic->next;
pcPic = iterPic->data;
}
3.erase函数实现问题
//destroy_node也销毁了数据 void TComList_pTComPic_destroy_node(TComList_pTComPic* position) { if(position->data) { free(position->data); position->data = NULL; } if(position) { free(position); position = NULL; } }
erase函数调用destroy_node,也销毁了数据,但是前面的iterPicExtract 交换位置,data指向了同一对象,然后的erase把这个对象也释放了。
而原本的rcListPic.erase (iterPicExtract)函数并没有释放对象。所以对data(为指针类型)的销毁,只因是销毁指针本身(=NULL),而不是销毁所指向的对象。应把free(position->data); 注释掉。