簡體   English   中英

C ++是否有java.lang.Number的等效項?

[英]Is there a C++ equivalent of java.lang.Number?

我正在嘗試創建一個std::vector ,它可以采用C ++中的任何數字數據類型(char,short,int,long,float和double)。

在Java中,我可以創建List<Number> list = ArrayList<Number>();

在C ++中是否存在等效項(最好是<= C ++ 03)。 如果沒有,實現此目標的最佳方法是什么?

PS-我真的不想每種數據類型都有一個向量:/

您想要的簡單方法是:

enum datatype
{
    dt_none,
    dt_char,
    dt_uchar,
    dt_short,
    dt_ushort,
    dt_long,
    dt_ulong,
    dt_float,
    dt_double
};

struct Any
{
      datatype type; // To know what is stored inside union, not mandatory if you know that in another way
      union
      {
          char vchar;
          unsigned char vuchar;
          short vshort;
          unsigned short vushort;
          long vlong;
          unsigned long vulong;
          float vfloat;
          double vdouble;
      } data;
};

std::vector<Any> mydata;

您可以避免使用聯合,但是會占用更多內存(每個值的指針+實際大小),並且使用起來更復雜:

struct Any
{
     private:
         void * data;
         datatype type;

     public:
         Any():
             data(NULL),
             type(dt_none)
         {}

         ~Any()
         {
             deleteData();  
         }

         void deleteData()
         {
             // Because deleting a void * is UB, we have to check real datatype
             if (data != NULL)
             {
                 if (type == dt_char)
                     delete static_cast<char *>(data);
                 if (type == dt_uchar)
                     delete static_cast<unsigned char *>(data);
                 ....
             }   
         }

         datatype getType() const
         {
             return type;
         }

         void setChar(char v)
         {
             deleteData(); 
             data = new char(v);
             type = dt_char;
         } 


         char toChar() const
         {
             return *static_cast<char *>(data);
         } 

         .....

         void setDouble(double v)
         {
             deleteData();
             data = new double(v);
         }

         double toDouble() const
         {
             return *static_cast<double*>(data);
         }
};

一種可能的優化方法是使用指針存儲小型數據,以節省一些字節(但要小心!)。 但是,如果您存儲大量大類型數據,則union仍會更好。 另外,指針的大小取決於平台,因此很難選擇哪種類型可以直接存儲在指針中並具有可移植的代碼。 此外,在64位計算機上,指針的大小為8個字節,這也是double常見大小(因此,在這種情況下,將每種類型直接存儲在指針內部,這與union內存消耗相同,但實際上更為復雜且不安全):

struct Any
{
     private:
         void * data;
         datatype type;

     public:
         Any():
             data(NULL),
             type(dt_none)
         {}

         ~Any()
         {
             deleteData();
         }

         void deleteData()
         {
             // Because deleting a void * is UB, we have to check real datatype
             if (type != dt_char && type != dt_uchar && data != NULL)
             {
                 if (type == dt_double)
                     delete static_cast<double *>(data);
                 ....
             } 
             data = NULL;
         }

         datatype getType() const
         {
             return type;
         }

         void setChar(char v)
         {
             data = reinterpret_cast<void *>(v);
         } 


         char toChar() const
         {
             return static_cast<char>(reinterpret_cast<intptr_t>(data));
         } 

         .....

         void setDouble(double v)
         {
             deleteData();
             data = new double(v);
         }

         double toDouble() const
         {
             return *static_cast<double*>(data);
         }
};

話雖如此,您只有兩種簡單的解決方案(IMHO):

  • 如果您確實想節省內存,則必須為每種類型使用向量。
  • 或使用union

PS:您也可以看看boost::any類的第三方庫。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM