boost::any原始碼分析 (轉)

amyz發表於2007-08-16
boost::any原始碼分析 (轉)[@more@]

  Boost::any分析:

:namespace prefix = o ns = "urn:schemas--com::office" /> 

boost::any是一個能代表任何型別的物件,正如COM庫的Variant變數型別,以及中的。不同的是,Variant的做法是包含所有可能型別的一個成員實現,浪費空間,而則boost::any藉助於模板,沒有空間浪費。

Variant的大致實現是:

Class Cvariant

{

    int   iData;

      long lData;

    ….

    Int  type;

}

而boost::any則使用模板,依靠兩個內部類來封裝實際資料(PlaceFolder和Folder),並對外暴露一個叫做Type()的暴露實際資料的型別。

為了方便分析其程式碼,現展示一個簡單的測試程式碼:

#include "stdafx.h"

#include

#include

#include "boost/any.hpp"

 

typedef std::list<:any> list_any;

//關鍵部分:可以存放任意型別的物件

void fill_list(list_any& la)

{

 //存放常數

 la.push_back(10

  //存放字串物件,

 la.push_back( std::string("dyunze") );

  //注意la.push_back(“dyunze”)錯誤,因為會被當錯字串陣列

}

//根據型別進行顯示:

void show_list(list_any& la)

{

  list_any::iterator it;

  boost::any  anyone;

  for( it = la.begin(); it != la.end(); it++ )

  {

    anyone = *it;

    if( anyone.type() == typeid(int) )

      std::cout<<:any_cast>(*it)<<:endl>

    else if( anyone.type() == typeid(std::string) )

      std::cout<<:any_cast>(*it).c_str()<<:endl>

  }

}

//主部分:

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

{

  list_any la;

  fill_list(la);

 

  show_list(la);

  return 0;

}

以下是我整理了後的boost::any的關鍵程式碼,(只是為了說明,可能無法直接執行,如需要完整程式碼,請到boost庫。)如下所示:

  class any

  {

public:

    //模板建構函式,引數可以是任意型別,真正的資料儲存在content中

  template

  any(const ValueType & value): content(new holder(value))

  {

  } 

    //解構函式,刪除儲存資料的content物件

  ~any()

  {

  delete content;

  }

  //一個placeholde物件指標,只想其子類folder的一個實現

 // 即content( new holder(value) )語句

  placeholder * content;

  public:

 

 //查詢真實資料的型別,拆葙時有用。

  const std::type_info & type() const

  {

  return content ? content->type() : typeid(void);

  }

  /**一個稻草人,存在好處是沒有模板引數,可以直接申明,

  *如:  placeholder * content;

 *如果使用子類folder則這能用older

  *content而申明時Type還不確定

*/

  class placeholder

  {

  public: 

  virtual ~placeholder()

  {

  }

  public:

  virtual const std::type_info & type() const = 0;

  virtual placeholder * clone() const = 0; 

  };

 //真正儲存和獲取資料的類。

  template

  class holder : public placeholder

  {

  public:

  holder(const ValueType & value)

  : held(value)

  {

  }

  public:

  virtual const std::type_info & type() const

  {

  return typeid(ValueType);

   }

 

  virtual placeholder * clone() const

  {

  return new holder(held);

  }

 

  public:

    //真正的資料,就儲存在這裡

  ValueType held;

  };

};

/**

 *獲取content->helder資料的方法。

 *

 */

  template

  ValueType * any_cast(any * operand)

  {

    return operand && operand->type() == typeid(ValueType) ?  &static_cast<:holder> *>(operand->content)->held : 0;

}

 

以上就是boost::any的關鍵部分,其實很短小,但是,功能上非常強大,特別是在配合容器使用時。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-962489/,如需轉載,請註明出處,否則將追究法律責任。

相關文章