Хранить и извлекать различные типы данных в объекте - PullRequest
2 голосов
/ 07 апреля 2020

Я хочу хранить и извлекать разные типы данных в одном объекте. Это будет поздно интерфейсом к базе данных.

Типы Basi c (char, short, int, float, double, ...) должны go объединиться в единое целое, чтобы сэкономить место для хранения. Кроме того, я хочу хранить std::string и std::vector. Хранение осуществляется путем перегрузки оператора присваивания, извлечение выполняется путем перегрузки оператора преобразования. Код ниже является урезанной версией, работающей с int, double и std::string.

Пока части int и double работают нормально, часть std::string не работает. Я также не уверен, является ли перегрузка оператора самым элегантным способом ввода и вывода данных. Я ограничен C ++ 11, поэтому std::any не вариант.

#include <string>

class mydata {
private:

   enum {
      TID_INT,
      TID_DOUBLE,
      TID_STRING
   };

   int m_type_id; // stores one of TID_xxx

   // this object should be able to store int, double, std::string
   union {
      int   m_int;
      double m_double;
   } m;
   std::string m_string;

public:
   // Default constructor
   mydata() { m_type_id = 0; }

   // Overloading the Assignment Operator
   template <typename T>
   const T &operator=(const T &v) {
      if (typeid(v) == typeid(int)) {
         m_type_id = TID_INT;
         m.m_int = v;
      } else if (typeid(v) == typeid(double)) {
         m_type_id = TID_DOUBLE;
         m.m_double = v;
      } else if (typeid(v) == typeid(const char *)) {
         m_type_id = TID_STRING;
         // this fails -->
         //m_string = std::string(v);
      }
      return v;
   }

   operator int() {
      if (m_type_id == TID_INT)
         return m.m_int;
      else if (m_type_id == TID_DOUBLE)
         return (int) m.m_double;
      return 0; // maybe throw an exception here
   }

   operator double() {
      if (m_type_id == TID_INT)
         return (double)m.m_int;
      else if (m_type_id == TID_DOUBLE)
         return m.m_double;
      return 0;
   }

};

/*------------------------------------------------------------------*/

int main() {
   mydata d1, d2, d3;

   d1 = 123;     // store an int
   d2 = 456.789; // store a double

   int i = d1;
   i = d2;

   double d = d1;
   d = d2;

   // this fails --->
   // d3 = "Hello"; // store a string

   return 1;
}

1 Ответ

0 голосов
/ 08 апреля 2020

Наконец-то разобрался. Я должен разделить оператор присваивания между различными типами. Также необходимо перегрузить операторы преобразования для получения значений разных типов. Вот код:

#include <string>

class mydata {
private:

   enum {
      TID_INT,
      TID_DOUBLE,
      TID_STRING
   };

   int m_type_id; // stored one of TID_xxx

   // this object stored int, double, std::string
   union {
      int   m_int;
      double m_double;
   };
   std::string m_string;

public:
   // Default constructor
   mydata() : m_type_id(0), m_int(0) {}

   // Overloading the Assignment Operator
   const int &operator=(const int &v) {
      m_type_id = TID_INT;
      m_int = v;
      return v;
   }
   const double &operator=(const double &v) {
      m_type_id = TID_DOUBLE;
      m_double = v;
      return v;
   }
   const std::string &operator=(const std::string &v) {
      m_type_id = TID_STRING;
      m_string = v;
      return v;
   }

   // overloading the conversion operators
   operator std::string() {
      return m_string;
   }

   template <typename T>
   operator T() {
      if (m_type_id == TID_INT)
         return (T)m_int;
      else if (m_type_id == TID_DOUBLE)
         return (T)m_double;
      return 0;
   }
};

/*------------------------------------------------------------------*/

int main() {
   mydata d1, d2, d3;

   d1 = 123;     // store an int
   d2 = 456.789; // store a double

   int i = d1;
   i = d2;

   double d = d1;
   d = d2;

   d3 = "Hello";
   std::string s = d3;

   return 1;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...