如何设计C ++类?

更新时间:2024-05-03 下载TXT文档 下载Word文档

我用C ++在MFC中编写了一个应用程序。 我需要编写一个类,该类可以保存从数据库加载的所有数据,这些数据可能包含每种数据类型,例如int,字符串,字节,布尔值,日期时间等。 我们可能会过滤,交换列或对这些数据进行排序。 例如:

int int string bool    double  float .... string
0    1  "a"    false   3.14    3.0       "b"
1    2  "5"    true    3.22    4         "c"

注意:
出于对我们的考虑,我们没有使用SQL进行排序或过滤。

我们编写了以下课程,如果有人有更好的建议,请编写示例课程供使用,谢谢!

#ifndef __LIST_DATA_MODEL_H__
#define __LIST_DATA_MODEL_H__

#include <vector>
using std::vector;

///implement a pure virtual base class; parameters of function is a void pointer, 

class FieldType
{
public:
 enum {
  TypeChar    = 0,
  TypeString  = 1,

  TypeBool    = 2,

  TypeShort   = 3,
  TypeUShort  = 4,

  TypeInt     = 5,
  TypeUInt    = 6,

  TypeLong    = 7,
  TypeULong   = 8,

  TypeLongLong  = 9,
  TypeULongLong = 10,

  TypeFloat     = 11,
  TypeDouble    = 12
 };
};

template <typename _ValueType, typename _SyncType>
class Column
{
protected:
 CString       m_szFieldName;
 vector<_ValueType> m_vValues;

public:
 Column();
 Column(CString szFieldName);
 Column(const Column& other);
 virtual ~Column();

public:
 virtual BOOL LoadData(...);

public:
 ///This function will call LoadData function to re-load data, 
 ///if subclass this class, please implement your LoadData function 
 ///if you want additional operation when load data.
 CALLBACK BOOL Update();

public:
 const int   ValueCount() const;
 const CString&  FieldName() const;
 const _ValueType&   ValueAt(int iPos) const;

 ///Before you call LoadData function or Update Function, the values will not updated;
 void SetFieldName(const CString& szFieldName);

 void SetValue(const _ValueType& val, int iPos);
};

template<class _Type>
class DataItem
{
protected:
 _Type _value;

public:
 DataItem();
 DataItem(const DataItem& other)
 {
  _value = other._value;
 };
 DataItem(const _Type& val)
 {
  _value = val;
 };
 virtual ~DataItem()
 {
 };

public:
 const _Type& GetValue()
 {
  return _value;
 };
 void SetValue(const _Type& value)
 {
  _value = value;
 };
 void ResetValue()
 {
  _value = _Type();
 };
public:
 bool operator ==(DataItem& right)
 {
  return _value == right._value;
 };
 bool operator <(const DataItem& right)
 {
  return _value < right._value;
 };
 const DataItem& operator =(const DataItem& right)
 {
  if(this == &right)
   return *this;

  _value = right._value;

  return *this;
 };

 virtual DataItem* Clone()
 {
  return new DataItem(*this);
 };
};

typedef DataItem<int>  IntItem;
typedef DataItem<float>  FloatItem;
typedef DataItem<double> DoubleItem;
typedef DataItem<CString> StringItem;
typedef DataItem<bool>      BoolItem;
typedef DataItem<TCHAR>     CharItem;
typedef DataItem<char>      ByteItem;
typedef DataItem<CString>   CStringItem;

#endif
  • _V是编译器和标准库的保留前缀,因此_ValueType是非法名称。 _A-_Z同样适用,因此您需要清除一些名称。 您可以在所有情况下将其删除; 您已加上前缀的所有名称都已作用域,没有全局名称。
  • 那么您对结构有什么建议吗?
  • 什么"考虑因素"导致您不使用SQL进行排序或过滤? SQL中的排序或筛选将更快,因为数据库可以利用索引,并且您可以避免将整个表传输到客户端。
  • 这段代码只是一个示例,希望有人可以给我更好的解决方案

我的第一种方法是使用Boost变体或Boost any而不是创建自己的。

我想知道您是否在模拟数据库行为,那么将数据存储在"类型"容器中是否有意义?由于将通过列名访问数据,因此您需要具有用于存储每个列的数据值并且具有列名到列类型映射关系的容器。无论如何,如果要存储数据及其类型,请考虑使用"枚举的字符串化"以下方法:

  • 创建自己的枚举
    类型的常量。就像枚举MYTYPE {
    MYINT,MYFLOAT,...}
  • 在将每个字符串枚举下的数据字符串化之后,写出DB信息。
  • 将字符串化的枚举及其数据读入一个字符串化的容器,如std::vector
  • 从字符串化枚举中提取实际的枚举类型,然后使用简单的switch case语句,将字符串化数据转换为实际数据。
  • 有关如何创建字符串化枚举和使用它们的信息,请点击此处和此处的链接。宏的方法。或者,您可以使用需要使用boost的模板化方法(仅提示:-))。 {短码网-DuanMa.NET}

    template<typename ENUM>
    class Stringifier<ENUM, typename boost::enable_if<boost::is_enum<ENUM> >::type> {
      static const char * values[]; // array with the enum strings.
      static std::size_t size;      // Number of elements of the ENUM string arrays.
    public:
      /// Global static instance of the Stringifier.
      static Stringifier & getInstance()
      {
        static Stringifier globalInstance;
        return globalInstance;
      }
      // Returns the string representation of the ENUM value \a e as a C string.
      // If string is not available an exception is thrown.
      virtual void str(ENUM const & e, std::string & s) const
      {
        if(e >= 0 && e < int(size))
          s = values[e];
        else // throw exception
         ;
      }
    
      // Returns the ENUM value of the string representation of an ENUM value if possible,
      // ENUM(0) otherwise or ENUM(size) if you like.
      virtual bool value(std::string const & str, ENUM & v) const
      {
        std::size_t i = 0;
        for(; i < size; ++i)
          if(values[i] == str) break;
        bool ok = (i != size);
        v = ok ? ENUM(i) : ENUM(0);
        return ok;
      }
    };

    在上面的类中,将您的枚举用作" ENUM"。

    注意:字符串化会降低性能。因此这种方法比较慢。

    有关您的代码的几点:

    • 正如MSalters指出的那样,像_ValueType这样的名称
      __LIST_DATA_MODEL_H__
      在用户代码中是非法的。
    • 如果虚拟BOOL LoadData(...)是函数的真实签名,则这也是非法的-在省略号之前必须至少有一个实际参数
    • 似乎未使用_SyncType模板参数
    • 您对所有枚举值进行编号的事实使我暗中怀疑您打算稍后显式使用这些数字-这是一种不好的做法
    • 我真的看不出_ValueTypes自己不做什么

    有什么理由不使用COM数据类型_variant_t?

    • 是不是跨平台的?
    • MFC也不跨平台

    对我来说,这似乎过于复杂。我会将column实现为适当类型的简单stl向量,然后根据需要从中进行发展。尽量不要对这个数据结构考虑得太硬,否则您将创建一个过于复杂的设计。

    以上就是短码网小编为大家整理的《如何设计C ++类?》相关内容,希望大家喜欢。

    本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

    如若内容造成侵权/违法违规/事实不符,请将联系本站反馈,一经查实,立即处理!

    如何设计C ++类?》文档下载仅供参考学习,下载后请在24小时内删除。

    转载注明出处:https://www.duanma.net/article/7c51f332033.html

    回到顶部