簡體   English   中英

如何設計C ++類?

[英]How to design a C++ class?

我用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

我的第一種方法是使用Boost變體Boost any而不是創建自己的。

有什么理由不使用COM數據類型_variant_t?

有關您的代碼的幾點:

  • 正如MSalters指出的那樣,在用戶代碼中,諸如_ValueType__LIST_DATA_MODEL_H__類的名稱是非法的。
  • 如果虛擬BOOL LoadData(...)是函數的真實簽名,則這也是非法的-在省略號之前必須至少有一個實際參數
  • 似乎未使用_SyncType模板參數
  • 您對所有枚舉值進行編號的事實使我暗中懷疑您打算稍后顯式使用這些數字-這是一種不好的做法
  • 我真的看不出_ValueTypes自己不做什么

我想知道您是否在模擬數據庫行為,那么將數據存儲在“類型”容器中是否有意義? 由於將通過列名訪問數據,因此您需要具有用於存儲每個列的數據值並且具有列名到列類型映射關系的容器。 無論如何,如果要存儲數據及其類型,請考慮使用“枚舉的字符串化”以下方法:

  1. 為類型創建自己的枚舉常量。 就像枚舉MYTYPE {MYINT,MYFLOAT,...}
  2. 在每個stringed-enum下將數據字符串化之后,寫出DB信息。
  3. 將字符串化的枚舉及其數據讀取到一個字符串化的容器中,例如std::vector<string>
  4. 字符串化枚舉中提取實際的枚舉類型,然后使用簡單的switch case語句,將字符串化數據轉換為實際數據。

有關如何創建字符串化枚舉和使用它們的信息,請單擊此處此處的鏈接。 宏的方法。 或者,您可以使用需要使用boost的模板化方法(僅提示:-))。

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”。

注意 :字符串化會降低性能。 因此這種方法比較慢。

對我來說,這似乎過於復雜。 我會將column實現為適當類型的簡單stl向量,然后根據需要從中進行發展。 盡量不要對這個數據結構考慮得太硬,否則您將創建一個過於復雜的設計。

暫無
暫無

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

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