C++山寨C#中的DataTable

简单介绍一下DataTable。DataTable主要基于表、行、单元格。行用集合包装单元格,表用集合包装行,大致就是这样。DataColumn表示单元格,DataColumn中的字段还挺多的,在实际应用中我们可能只想用它来存一个int型的数据;DataColumnCollection中用一个ArrayList封装DataColumn,表示一些单元格的集合;DataRow直接在DataColumnCollection的基础上提供一些方法,成为行记录。而DataRowCollection则用集合的方式封装DataRow成为表,但它不是以线性、链表等方式,而是基于红黑树RBTree<DataRow>,主要是查询和删除比较方便,而DataTable则是DataRowCollection的封装,对看了DataTable整个实现的大致代码,我不得吐槽一下:这它妈是把牛刀,我们每天用它来切菜,用着还挺方便。DataTable提供了很强大的功能,但是我们基本不需要,有时候基本上是得到一个DataTable,啥都不做,直接绑定,最常用的也就Update和Insert,Select和Delete则次之。当然你会说避免使用DataTable,当然还有人说C#......

OK废话到此结束,今天我想做说的是用C++来实现DataTable。大致思路还是按照C#中的来,功能没有C#中的强大,但增删改查的功能还是有的,基本还是个人练习,把代码放出来跟大家讨论一下。基本上是STL中几个集合的运用。在我的实现在并没有使用红黑树,而是用list<DataRow*>代替了,主要类的头文件如下:

DataColumn的实现代码如下,主要是对几个字段的封装。源码共享

#pragma once
class DataTable;
#include <iostream>
using namespace std; 

template<typename T>
class TDataColumn
{
public:
    TDataColumn():columnName(string()),caption(string())
    {
         
    }

    TDataColumn(const string& _columnName):columnName(_columnName),caption(string())
    {
         
    }
     
    virtual ~TDataColumn()
    {
    
    }

    void Caption(const string& _caption)
    {
        caption=_caption;
    }
    string Caption()
    {
        return caption.size() ?caption:columnName; 
    }

    void  ColumnName(const string& _columnName)
    {
        columnName=_columnName;
    }
    string ColumnName()
    {
        return columnName;
    }

    void Value(const T& _value)
    {
        value=_value;
    }
    T Value()
    {
        return value;
    }
  
    int ObjectId()
    {
        return objectId;
    }

    void Table(DataTable* tb)
    {
        table=tb;
    }

    DataTable* Table()
    { 
        return table;
    }

    string TypeName()
    {
        return typeid(T).name();
    }
     
protected: 
    int objectId; 
    string columnName;
    string caption;
    T value;
    DataTable* table;
}; 
 

class DataColumn:public TDataColumn<string>
{
public:
    friend class DataColumnCollection;
    friend class DataTable;
    DataColumn():TDataColumn<string>() 
    {
         objectId=++objectCountId;
    }

    DataColumn(const DataColumn& dc)
    {
        *this=dc; 
    }

    DataColumn& operator=(const DataColumn& dc)
    {
        objectId=++objectCountId;
        columnName=dc.columnName;
        caption=dc.caption;
        value=dc.value;
        table=dc.table;
        return *this;
    }

    DataColumn(const string& _columnName):TDataColumn<string>(_columnName)
    {
         objectId=++objectCountId;
    }

    bool operator==(const DataColumn& dc)
    {
        return objectId==dc.objectId;
    }

    bool operator!=(const DataColumn& dc)
    {
        return objectId!=dc.objectId;
    }

    bool operator<(const DataColumn& dc)
    {
        return objectId<dc.objectId;
    }

    bool operator>(const DataColumn& dc)
    {
        return objectId>dc.objectId;
    }

    void Show()
    {
        cout<<"columnName:"<<columnName.data()<<",caption:"<<Caption().c_str()<<",value:"<<value.data()<<endl;
    }
   
private: 
    static volatile int objectCountId;
}; 


其他文件的头文件如下:

#pragma once
#include <iostream>
using namespace std; 
#include <assert.h> 
#include <vector> 
#include <list>
#include <map>
#include "DataColumn.h" 
#include "StringHelper.h"

class DataColumnCollection;
class DataRow;
class DataRowCollection;
class DataTable;

class DataColumnCollection
{
public:
     friend class DataTable;
     friend class DataRow;
     friend class DataRowCollection;
     DataColumnCollection(DataTable* table);
     ~DataColumnCollection();
     void Add(DataColumn* dc);
     void Add(DataColumn* dc,size_t index);
     
     DataColumn& Add(const string& columnName);

     bool Contains(const string& columnName);
     void Clear();
     size_t Count(); 
     int IndexOf(const string& columnName);
      
     void Remove(DataColumn& dc);
     void Remove(const string& columnName);
     void RemoveAt(size_t index);

     void CopyTo(DataColumnCollection* arr, size_t index);

     DataColumn& operator[](size_t index);
     DataColumn& operator[](const string& columnName);
      
     void Table(DataTable* tb);
     DataTable* Table();
private:
    void Add(DataColumn* dc,size_t index,DataColumnCollection* collect);
    void RemoveAt(size_t index,DataColumnCollection* collect);
    void InitData();
    DataColumnCollection(); 
    vector<DataColumn*> dlist;
    map<string,DataColumn*> nameList;
    DataTable* table;
};

class DataRow
{
public:
    friend class DataTable;
    friend class DataRowCollection;
    friend class DataColumnCollection;
    ~DataRow();
    void Table(DataTable* tb); 
    DataTable* Table();

    DataColumnCollection& Columns();
    DataColumn& operator[](size_t index);
    DataColumn& operator[](const string& columnName);
    bool operator=(const DataRow& dr);
private:
    DataRow();
    void Remove(DataColumn& dc);
    void RemoveAt(size_t index); 
    DataColumnCollection* columns;
    DataTable* table;    
    int rowId;
    static volatile int rowIdCount;
};

class DataRowCollection
{
public:
     friend class DataTable;
     friend class DataColumnCollection;
     DataRowCollection(DataTable* table);
     ~DataRowCollection();
     void Add(DataRow* dc);  
     void Clear();
     size_t Count();  
     void Remove(DataRow* dc); 
     void RemoveAt(size_t index); 
     DataRow& operator[](size_t index); 
     void Table(DataTable* tb);
     DataTable* Table();
private:
    DataRowCollection(); 
    list<DataRow*> drlist; 
    DataTable* table;
};


class DataTable
{
public:
    friend class DataColumnCollection;
    friend class DataRowCollection;
    DataTable();
    DataTable(const string& _tableName);
    ~DataTable();

    DataColumnCollection& Columns();
    DataRowCollection& Rows();

    string TableName();
    void TableName(const string& _tableName);
    DataRow& operator[](size_t index);
    void Clear(); 
    DataRow* NewRow();
    vector<DataRow*>* Select(const string& columnName,const string& value) ;
private:
    void InitData();
    DataColumnCollection* dcCollect;
    DataRowCollection* drCollect;
    string tableName;
};

测试代码如下:

#include <iostream>
using namespace std;
#include <sstream>
#include "DataColumn.h" 
#include "DataTable.h"
#include "OperationTimer.h"
 
int main( )
{  
    DataTable dt;
    for(size_t i=0;i<10;i++)
    {
        string s("column");
        s.push_back(char('0'+i));
        DataColumn *dc=new DataColumn(s); 
        dt.Columns().Add(dc);
    }

    for(int j=0;j<10;j++)
    {
        DataRow* dr=dt.NewRow();
        for(int i=0;i<10;i++)
        {
            string s("row");
            s.push_back(char('0'+j));
            s.push_back(char('0'+i));
            (*dr)[i].Value(s)  ;
        }
        dt.Rows().Add(dr);
    }
    
    int rowCount=dt.Rows().Count();
    int columnCount=dt.Columns().Count();
    cout<<""<<rowCount<<""<<columnCount<<""<<endl;
    rowCount=rowCount/2;
    columnCount=columnCount/2;
    cout<<""<<rowCount<<""<<columnCount<<"列的值为:"<<dt[rowCount][columnCount].Value().c_str()<<endl;

    dt.Columns().Add(new DataColumn("column10"));
    dt.Columns().Add(new DataColumn("column11"));
    cout<<"新增两列后:"<<endl;
    rowCount=dt.Rows().Count();
    columnCount=dt.Columns().Count();
    cout<<""<<rowCount<<""<<columnCount<<""<<endl;
    rowCount=rowCount/2;
    columnCount=columnCount/2;
    cout<<""<<rowCount<<""<<columnCount<<"列的值为:"<<dt[rowCount][columnCount].Value().c_str()<<endl;
    cout<<"删除一行一列后:"<<endl;
    dt.Columns().RemoveAt(4); 
    dt.Rows().RemoveAt(2);

    rowCount=dt.Rows().Count();
    columnCount=dt.Columns().Count();
    cout<<""<<rowCount<<""<<columnCount<<""<<endl;
    rowCount=rowCount/2;
    columnCount=columnCount/2;
    cout<<""<<rowCount<<""<<columnCount<<"列的值为:"<<dt[rowCount][columnCount].Value().c_str()<<endl<<endl;

    cout<<"查询列名为column3,值为row43的行,数据如下:"<<endl;
    vector<DataRow*>* vect=dt.Select("column3","row43");
    for(size_t i=0;i<vect->size();i++)
    {
        DataColumnCollection& dcCollect= (*vect)[i]->Columns();
        for(size_t j=0;j<dcCollect.Count();j++)
        {
            dcCollect[j].Show();
        }
    }
    delete vect;  



    getchar();
    return 0;
}

 结构截图:

在吐个槽,STL中的map<key,value>中的key竟然可以用string呢,好神奇哦,哈哈哈

C/C++程序员在自涅中需找快感;C#/JAVA则全靠意淫。是这样吗?

posted @ 2013-05-31 11:26  啊汉  阅读(6940)  评论(12编辑  收藏  举报