如何设计C++;上课? 我用C++编写了一个应用于MFC的应用程序。我需要编写一个类来保存从数据库加载的所有数据,这些数据可能包含各种数据类型,例如int、string、byte、boolean、datetime等等。我们可以对这些数据进行筛选、交换列或排序。例如: 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进行排序或筛选,因为我们有自己的考虑 我们已经写了下面的类,如果有人有更好的建议,请写一个示例类供使用,提前感谢如何设计C++;上课? 我用C++编写了一个应用于MFC的应用程序。我需要编写一个类来保存从数据库加载的所有数据,这些数据可能包含各种数据类型,例如int、string、byte、boolean、datetime等等。我们可以对这些数据进行筛选、交换列或排序。例如: int int string bool double float .... string 0 1 "a" false 3.14 3.0 "b" 1 2 "5" true 3.22 4 "c",c++,design-patterns,oop,class-design,C++,Design Patterns,Oop,Class Design,注意: 我们没有使用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 po
#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
\ifndef\u列表\u数据\u模型\u H__
#定义\u列表\u数据\u模型\u H__
#包括
使用std::vector;
///实现一个纯虚拟基类;函数的参数是空指针,
类字段类型
{
公众:
枚举{
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
};
};
模板
类列
{
受保护的:
CString m_szFieldName;
向量m_v值;
公众:
列();
列(CString szFieldName);
列(常数列和其他);
虚拟列();
公众:
虚拟BOOL加载数据(…);
公众:
///此函数将调用LoadData函数重新加载数据,
///如果子类化这个类,请实现LoadData函数
///如果在加载数据时需要其他操作。
回调BOOL Update();
公众:
常量int ValueCount()常量;
常量CString&FieldName()常量;
const_ValueType&ValueAt(intipos)const;
///在调用LoadData函数或Update函数之前,值不会更新;
void SetFieldName(const CString和szFieldName);
无效设置值(常量值类型和值,整数IPO);
};
模板
类数据项
{
受保护的:
_类型_值;
公众:
数据项();
数据项(常量数据项和其他)
{
_值=其他值;
};
数据项(常数类型和值)
{
_值=val;
};
虚拟~DataItem()
{
};
公众:
常量类型和GetValue()
{
返回_值;
};
无效设置值(常数类型和值)
{
_价值=价值;
};
void ResetValue()
{
_值=_Type();
};
公众:
布尔运算符==(数据项和右侧)
{
返回_值==右。_值;
};
bool运算符不使用COM数据类型“变量”的任何原因?不使用COM数据类型“变量”的任何原因?关于代码的几点:
- 正如MSalters所指出的,像
\u ValueType
和\u列表\u数据\u模型\u H\u
在用户代码中是非法的
- 如果virtual BOOL LoadData(…)是函数的真实签名,那么这也是非法的-在省略号之前必须至少有一个实际参数
- 似乎未使用_SyncType模板参数
- 您对所有枚举值进行编号这一事实让我暗自怀疑您打算以后明确使用这些数字——这是一种糟糕的做法
- 我真的不知道你的类做了什么,而_值类型本身没有做什么
关于代码的几点:
- 正如MSalters所指出的,像
\u ValueType
和\u列表\u数据\u模型\u H\u
在用户代码中是非法的
- 如果virtual BOOL LoadData(…)是函数的真实签名,那么这也是非法的-在省略号之前必须至少有一个实际参数
- 似乎未使用_SyncType模板参数
- 您对所有枚举值进行编号这一事实让我暗自怀疑您打算以后明确使用这些数字——这是一种糟糕的做法
- 我真的不知道你的类做了什么,而_值类型本身没有做什么
我的第一种方法是使用或代替创建我自己的。我的第一种方法是使用或代替创建我自己的。这对我来说似乎太复杂了。我会将列作为适当类型的简单stl向量来实现,我会根据需要从中演化出来。尽量不要过多地考虑这个数据结构,否则您将创建一个过于复杂的设计。这对我来说似乎过于复杂。我会将列实现为一个适当类型的简单stl向量,并根据需要对此进行改进。尽量不要过多考虑此数据结构,否则您将创建一个过于复杂的设计。我想知道您是否在模拟DB行为,那么将数据存储在“类型”的容器中是否有意义?因为数据将通过列名访问,所以需要有存储每个列的数据值的容器,并且具有列名到列类型映射。无论如何,如果您想将数据与其类型一起存储,则使用“StrugIZAT”考虑以下方法。枚举的定义':-
创建自己的枚举
类型的常量。如枚举MYTYPE{
MYINT,MYFLOAT,…}
在对每个字符串化枚举下的数据进行字符串化后,写出数据库信息
将字符串化枚举及其数据读入字符串化容器,如std::vector
从字符串化枚举中提取实际枚举类型,然后使用简单的switch case语句将字符串化数据转换为实际数据
关于如何创建字符串化枚举并使用它们,请遵循link和.Macro的方法。或者您可以使用模板化方法,该方法需要使用boost,如下所示(仅提示:-))
模板
类架线机{
静态常量char*值[];//带有枚举字符串的数组。
静态std::size\u t size;//枚举字符串数组的元素数。
公众:
///架线器的全局静态实例。
静态字符串生成器&getInstance()
{
静态架线机;
回归全球立场;
}
//返回枚举值的字符串表示形式\a e作为C字符串。
//如果字符串不可用,将引发异常。
虚空str(枚举常量&e,std::string&s)常量
{
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;
}
};