【发布时间】:2019-09-15 14:00:59
【问题描述】:
我希望清楚我想做什么。
我想根据提供的对象的属性从数据库中获取数据,然后用检索到的数据填充这些属性。 因此,例如,如果用户定义了一个类
class Person
{
public:
int Id;
string Name;
};
然后当他调用MyDatabase.Instance.ExecQuery<Person>() 时,它应该返回填充信息的Person 对象。
我所做的是:用户应该将类定义如下:
class Person : public DBEntity
{
ENTITIY_PROP(Person , int, Id)
ENTITIY_PROP(Person , string, Name)
};
定义的宏确保将属性的名称和类型添加到_propsMeta。
现在,如何根据对象的名称设置对象的属性(参见ExecQuery)?
我的初步解决方案
我想添加将属性映射到设置属性的函数的map,但我不能拥有对具有不同签名的函数的引用的map。有任何想法吗?如果您认为我需要更改我的设计以完成我的需要 - 请告诉我。
template <typename T>
void ExecQuery()
{
static_assert(std::is_base_of<DBEntity, T>(), "a Class should inherit from DBEntity");
const auto& props = entity->GetPropsMeta();
auto row = GetData(props);
T entity = new T();
for (const auto& colName : row.Columns)
{
string val = row[colName];
// TODO: SET ENTITY'S PROPERTY colName with val
}
}
#define ENTITIY_PROP(Class, Type, Name) \
private: \
int _##Name; \
public: \
class Property_##Name { \
public: \
Property_##Name(Class* parent) : _parent(parent) \
{ \
_parent->SetPropMeta(#Name, #Type); \
} \
Type operator = (Type value) \
{ \
_parent->Set##Name(value); \
return _parent->Get##Name(); \
} \
operator Type() const \
{ \
return static_cast<const Class*>(_parent)->Get##Name(); \
} \
Property_##Name& operator =(const Property_##Name& other) \
{ \
operator=(other._parent->Get##Name()); return *this; \
}; \
Property_##Name(const Property_##Name& other) = delete; \
private: \
Class* _parent; \
} Name { this }; \
\
Type Get##Name() const { return _##Name; } \
void Set##Name(int value) { _##Name = value; } \
class DBEntity
{
private:
std::unordered_map<std::string, std::string> _propsMeta;
public:
const std::unordered_map<std::string, std::string>& GetPropsMeta() { return _propsMeta; }
};
【问题讨论】:
-
是的,你不能拥有不同签名的函数映射——你需要某种类型的擦除。最简单的解决方案就是将 std::any 或 boost::any 作为参数。
-
您是否绝对希望用户像这样创建 Person 类:
class Person { ENTITY_PROP(Person, int, Id), ENTITY_PROP(Person, string, Name)};?或者这也会起作用吗?MAKE_CLASS(Person, (int, Id), (string, Name))?我知道如何帮助您,但需要使用后一种形式。 -
你可以看看boost::hana,它允许自省。
标签: c++ visual-studio c++11 reflection visual-studio-2015