C++ C+中的动态对象+;?
我意识到我很可能会得到很多“你不应该那样做,因为……”的答案,这些答案是非常受欢迎的,我可能完全同意你的推理,但我很好奇这是否可能(正如我想象的那样) < >可以定义C++中的动态/通用对象类型,在那里我可以动态创建在键值类型的系统中存储和检索的属性吗?例如:C++ C+中的动态对象+;?,c++,c++11,C++,C++11,我意识到我很可能会得到很多“你不应该那样做,因为……”的答案,这些答案是非常受欢迎的,我可能完全同意你的推理,但我很好奇这是否可能(正如我想象的那样) < >可以定义C++中的动态/通用对象类型,在那里我可以动态创建在键值类型的系统中存储和检索的属性吗?例如: MyType myObject; std::string myStr("string1"); myObject.somethingIJustMadeUp = myStr; 请注意,somethingistmadeup显然不是MyTy
MyType myObject;
std::string myStr("string1");
myObject.somethingIJustMadeUp = myStr;
请注意,somethingistmadeup
显然不是MyType
的定义成员,而是动态定义的。然后我可以做一些类似的事情:
if(myObject.somethingIJustMadeUp != NULL);
或
相信我,我意识到这有多么可怕,但我仍然好奇这是否可能,以及是否可以用一种将可怕程度降至最低的方式来完成。你可以用
std::map
做一些非常类似的事情:
std::map<std::string, std::string> myObject;
myObject["somethingIJustMadeUp"] = myStr;
您还可以检查值是否存在:
if(myObject.find ("somethingIJustMadeUp") != myObject.end())
std::cout << "Exists" << std::endl;
这还显示了如何使用获取存储在类型的对象中的值。您可以使用
std::map
执行非常类似的操作:
std::map<std::string, std::string> myObject;
myObject["somethingIJustMadeUp"] = myStr;
您还可以检查值是否存在:
if(myObject.find ("somethingIJustMadeUp") != myObject.end())
std::cout << "Exists" << std::endl;
这还显示了如何使用获取存储在类型的对象中的值。就是您想要的
例如:
#include <cppscript>
var script_main(var args)
{
var x = object();
x["abc"] = 10;
writeln(x["abc"]);
return 0;
}
#包括
变量脚本_main(变量args)
{
var x=object();
x[“abc”]=10;
书面形式(x[“abc”]);
返回0;
}
这是一个有效的C++。< /P> < P>是你想要的! 例如:
#include <cppscript>
var script_main(var args)
{
var x = object();
x["abc"] = 10;
writeln(x["abc"]);
return 0;
}
#包括
变量脚本_main(变量args)
{
var x=object();
x[“abc”]=10;
书面形式(x[“abc”]);
返回0;
}
这是一个有效的C++。
< p>是的,很可怕。D 这项工作进行了多次,取得了不同程度和不同程度的成功 QT有一个Qobject,与它们相关的一切都从它开始MFC有CubDeST,它和C++一样。 我不知道是否有办法让它变得不那么糟糕,我想如果你避免像瘟疫这样的多重继承(这是一个有用的语言特性),并重新实现stdlib,它会更好。但是如果你真的是这样的话,那么你可能在任务中使用了错误的语言
Java和C更适合这种编程风格 #注意:如果我看错了你的问题,请删除此答案。是的,这很糟糕D 这项工作进行了多次,取得了不同程度和不同程度的成功 QT有一个Qobject,与它们相关的一切都从它开始MFC有CubDeST,它和C++一样。 我不知道是否有办法让它变得不那么糟糕,我想如果你避免像瘟疫这样的多重继承(这是一个有用的语言特性),并重新实现stdlib,它会更好。但是如果你真的是这样的话,那么你可能在任务中使用了错误的语言
Java和C更适合这种编程风格#注意:如果我看错了您的问题,请删除此答案。签出签出使用RTTI多态性,这可能是一个解决方案
#include <map>
#include <memory>
#include <iostream>
#include <stdexcept>
namespace dynamic
{
template<class T, class E>
T& enforce(T& z, const E& e)
{ if(!z) throw e; return z; }
template<class T, class E>
const T& enforce(const T& z, const E& e)
{ if(!z) throw e; return z; }
template<class Derived>
class interface;
class aggregate;
//polymorphic uncopyable unmovable
class property
{
public:
property() :pagg() {}
property(const property&) =delete;
property& operator=(const property&) =delete;
virtual ~property() {} //just make it polymorphic
template<class Interface>
operator Interface*() const
{
if(!pagg) return 0;
return *pagg; //let the aggregate do the magic!
}
aggregate* get_aggregate() const { return pagg; }
private:
template<class Derived>
friend class interface;
friend class aggregate;
static unsigned gen_id()
{
static unsigned x=0;
return enforce(++x,std::overflow_error("too many ids"));
}
template<class T>
static unsigned id_of()
{ static unsigned z = gen_id(); return z; }
aggregate* pagg;
};
template<class Derived>
class interface: public property
{
public:
interface() {}
virtual ~interface() {}
unsigned id() const { return property::id_of<Derived>(); }
};
//sealed movable
class aggregate
{
public:
aggregate() {}
aggregate(const aggregate&) = delete;
aggregate& operator=(const aggregate&) = delete;
aggregate(aggregate&& s) :m(std::move(s.m)) {}
aggregate& operator=(aggregate&& s)
{ if(this!=&s) { m.clear(); std::swap(m, s.m); } return *this; }
template<class Interface>
aggregate& add_interface(interface<Interface>* pi)
{
m[pi->id()] = std::unique_ptr<property>(pi);
static_cast<property*>(pi)->pagg = this;
return *this;
}
template<class Inteface>
aggregate& remove_interface()
{ m.erase[property::id_of<Inteface>()]; return *this; }
void clear() { m.clear(); }
bool empty() const { return m.empty(); }
explicit operator bool() const { return empty(); }
template<class Interface>
operator Interface*() const
{
auto i = m.find(property::id_of<Interface>());
if(i==m.end()) return nullptr;
return dynamic_cast<Interface*>(i->second.get());
}
template<class Interface>
friend aggregate& operator<<(aggregate& s, interface<Interface>* pi)
{ return s.add_interface(pi); }
private:
typedef std::map<unsigned, std::unique_ptr<property> > map_t;
map_t m;
};
}
/// this is a sample on how it can workout
class interface_A: public dynamic::interface<interface_A>
{
public:
virtual void methodA1() =0;
virtual void methodA2() =0;
};
class impl_A1: public interface_A
{
public:
impl_A1() { std::cout<<"creating impl_A1["<<this<<"]"<<std::endl; }
virtual ~impl_A1() { std::cout<<"deleting impl_A1["<<this<<"]"<<std::endl; }
virtual void methodA1() { std::cout<<"interface_A["<<this<<"]::methodA1 on impl_A1 in aggregate "<<get_aggregate()<<std::endl; }
virtual void methodA2() { std::cout<<"interface_A["<<this<<"]::methodA2 on impl_A1 in aggregate "<<get_aggregate()<<std::endl; }
};
class impl_A2: public interface_A
{
public:
impl_A2() { std::cout<<"creating impl_A2["<<this<<"]"<<std::endl; }
virtual ~impl_A2() { std::cout<<"deleting impl_A2["<<this<<"]"<<std::endl; }
virtual void methodA1() { std::cout<<"interface_A["<<this<<"]::methodA1 on impl_A2 in aggregate "<<get_aggregate()<<std::endl; }
virtual void methodA2() { std::cout<<"interface_A["<<this<<"]::methodA2 on impl_A2 in aggregate "<<get_aggregate()<<std::endl; }
};
class interface_B: public dynamic::interface<interface_B>
{
public:
virtual void methodB1() =0;
virtual void methodB2() =0;
};
class impl_B1: public interface_B
{
public:
impl_B1() { std::cout<<"creating impl_B1["<<this<<"]"<<std::endl; }
virtual ~impl_B1() { std::cout<<"deleting impl_B1["<<this<<"]"<<std::endl; }
virtual void methodB1() { std::cout<<"interface_B["<<this<<"]::methodB1 on impl_B1 in aggregate "<<get_aggregate()<<std::endl; }
virtual void methodB2() { std::cout<<"interface_B["<<this<<"]::methodB2 on impl_B1 in aggregate "<<get_aggregate()<<std::endl; }
};
class impl_B2: public interface_B
{
public:
impl_B2() { std::cout<<"creating impl_B2["<<this<<"]"<<std::endl; }
virtual ~impl_B2() { std::cout<<"deleting impl_B2["<<this<<"]"<<std::endl; }
virtual void methodB1() { std::cout<<"interface_B["<<this<<"]::methodB1 on impl_B2 in aggregate "<<get_aggregate()<<std::endl; }
virtual void methodB2() { std::cout<<"interface_B["<<this<<"]::methodB2 on impl_B2 in aggregate "<<get_aggregate()<<std::endl; }
};
int main()
{
dynamic::aggregate agg1;
agg1 << new impl_A1 << new impl_B1;
dynamic::aggregate agg2;
agg2 << new impl_A2 << new impl_B2;
interface_A* pa = 0;
interface_B* pb = 0;
pa = agg1; if(pa) { pa->methodA1(); pa->methodA2(); }
pb = *pa; if(pb) { pb->methodB1(); pb->methodB2(); }
pa = agg2; if(pa) { pa->methodA1(); pa->methodA2(); }
pb = *pa; if(pb) { pb->methodB1(); pb->methodB2(); }
agg2 = std::move(agg1);
pa = agg2; if(pa) { pa->methodA1(); pa->methodA2(); }
pb = *pa; if(pb) { pb->methodB1(); pb->methodB2(); }
return 0;
}
#包括
#包括
#包括
#包括
命名空间动态
{
样板
T&E(T&z、施工E&E)
{如果(!z)抛出e;返回z;}
样板
施工测试与执行(施工测试与测试、施工测试与评估)
{如果(!z)抛出e;返回z;}
样板
类接口;
类骨料;
//多态不可压缩不可移动
类属性
{
公众:
属性():pagg(){}
属性(常量属性&)=删除;
属性和运算符=(常量属性&)=删除;
virtual~property(){}//只需使其多态即可
样板
操作员接口*()常量
{
如果(!pagg)返回0;
return*pagg;//让聚合发挥作用!
}
聚合*get_aggregate()常量{return pagg;}
私人:
样板
好友类接口;
好友类聚合;
静态无符号gen_id()
{
静态无符号x=0;
返回强制(++x,std::overflow_error(“ID过多”);
}
样板
()的静态无符号id_
{静态无符号z=gen_id();返回z;}
合计*pagg;
};
样板
类接口:公共属性
{
公众:
接口(){}
虚拟~interface(){}
无符号id()常量{return property::id_of();}
};
//密封可移动
类集合
{
公众:
聚合(){}
聚合(常量聚合&)=删除;
聚合和运算符=(常量聚合-)=删除;
聚合(聚合和&s):m(std::move(s.m)){
聚合和运算符=(聚合和运算符)
{if(this!=&s){m.clear();std::swap(m,s.m);}返回*this;}
样板
聚合和添加接口(接口*pi)
{
m[pi->id()]=std::unique_ptr(pi);
静态_cast(pi)->pagg=this;
归还*这个;
}
样板
聚合并删除_接口()
{m.erase[property::id_of()];返回*this;}
void clear(){m.clear();}
bool empty()常量{return m.empty();}
显式运算符bool()const{return empty();}
样板
操作员接口*()常量
{
auto i=m.find(属性::id_of());
如果(i==m.end())返回null ptr;
返回动态_cast(i->second.get());
}
样板
friend aggregate&operator这可以是一个解决方案,使用RTTI多态性
#include <map>
#include <memory>
#include <iostream>
#include <stdexcept>
namespace dynamic
{
template<class T, class E>
T& enforce(T& z, const E& e)
{ if(!z) throw e; return z; }
template<class T, class E>
const T& enforce(const T& z, const E& e)
{ if(!z) throw e; return z; }
template<class Derived>
class interface;
class aggregate;
//polymorphic uncopyable unmovable
class property
{
public:
property() :pagg() {}
property(const property&) =delete;
property& operator=(const property&) =delete;
virtual ~property() {} //just make it polymorphic
template<class Interface>
operator Interface*() const
{
if(!pagg) return 0;
return *pagg; //let the aggregate do the magic!
}
aggregate* get_aggregate() const { return pagg; }
private:
template<class Derived>
friend class interface;
friend class aggregate;
static unsigned gen_id()
{
static unsigned x=0;
return enforce(++x,std::overflow_error("too many ids"));
}
template<class T>
static unsigned id_of()
{ static unsigned z = gen_id(); return z; }
aggregate* pagg;
};
template<class Derived>
class interface: public property
{
public:
interface() {}
virtual ~interface() {}
unsigned id() const { return property::id_of<Derived>(); }
};
//sealed movable
class aggregate
{
public:
aggregate() {}
aggregate(const aggregate&) = delete;
aggregate& operator=(const aggregate&) = delete;
aggregate(aggregate&& s) :m(std::move(s.m)) {}
aggregate& operator=(aggregate&& s)
{ if(this!=&s) { m.clear(); std::swap(m, s.m); } return *this; }
template<class Interface>
aggregate& add_interface(interface<Interface>* pi)
{
m[pi->id()] = std::unique_ptr<property>(pi);
static_cast<property*>(pi)->pagg = this;
return *this;
}
template<class Inteface>
aggregate& remove_interface()
{ m.erase[property::id_of<Inteface>()]; return *this; }
void clear() { m.clear(); }
bool empty() const { return m.empty(); }
explicit operator bool() const { return empty(); }
template<class Interface>
operator Interface*() const
{
auto i = m.find(property::id_of<Interface>());
if(i==m.end()) return nullptr;
return dynamic_cast<Interface*>(i->second.get());
}
template<class Interface>
friend aggregate& operator<<(aggregate& s, interface<Interface>* pi)
{ return s.add_interface(pi); }
private:
typedef std::map<unsigned, std::unique_ptr<property> > map_t;
map_t m;
};
}
/// this is a sample on how it can workout
class interface_A: public dynamic::interface<interface_A>
{
public:
virtual void methodA1() =0;
virtual void methodA2() =0;
};
class impl_A1: public interface_A
{
public:
impl_A1() { std::cout<<"creating impl_A1["<<this<<"]"<<std::endl; }
virtual ~impl_A1() { std::cout<<"deleting impl_A1["<<this<<"]"<<std::endl; }
virtual void methodA1() { std::cout<<"interface_A["<<this<<"]::methodA1 on impl_A1 in aggregate "<<get_aggregate()<<std::endl; }
virtual void methodA2() { std::cout<<"interface_A["<<this<<"]::methodA2 on impl_A1 in aggregate "<<get_aggregate()<<std::endl; }
};
class impl_A2: public interface_A
{
public:
impl_A2() { std::cout<<"creating impl_A2["<<this<<"]"<<std::endl; }
virtual ~impl_A2() { std::cout<<"deleting impl_A2["<<this<<"]"<<std::endl; }
virtual void methodA1() { std::cout<<"interface_A["<<this<<"]::methodA1 on impl_A2 in aggregate "<<get_aggregate()<<std::endl; }
virtual void methodA2() { std::cout<<"interface_A["<<this<<"]::methodA2 on impl_A2 in aggregate "<<get_aggregate()<<std::endl; }
};
class interface_B: public dynamic::interface<interface_B>
{
public:
virtual void methodB1() =0;
virtual void methodB2() =0;
};
class impl_B1: public interface_B
{
public:
impl_B1() { std::cout<<"creating impl_B1["<<this<<"]"<<std::endl; }
virtual ~impl_B1() { std::cout<<"deleting impl_B1["<<this<<"]"<<std::endl; }
virtual void methodB1() { std::cout<<"interface_B["<<this<<"]::methodB1 on impl_B1 in aggregate "<<get_aggregate()<<std::endl; }
virtual void methodB2() { std::cout<<"interface_B["<<this<<"]::methodB2 on impl_B1 in aggregate "<<get_aggregate()<<std::endl; }
};
class impl_B2: public interface_B
{
public:
impl_B2() { std::cout<<"creating impl_B2["<<this<<"]"<<std::endl; }
virtual ~impl_B2() { std::cout<<"deleting impl_B2["<<this<<"]"<<std::endl; }
virtual void methodB1() { std::cout<<"interface_B["<<this<<"]::methodB1 on impl_B2 in aggregate "<<get_aggregate()<<std::endl; }
virtual void methodB2() { std::cout<<"interface_B["<<this<<"]::methodB2 on impl_B2 in aggregate "<<get_aggregate()<<std::endl; }
};
int main()
{
dynamic::aggregate agg1;
agg1 << new impl_A1 << new impl_B1;
dynamic::aggregate agg2;
agg2 << new impl_A2 << new impl_B2;
interface_A* pa = 0;
interface_B* pb = 0;
pa = agg1; if(pa) { pa->methodA1(); pa->methodA2(); }
pb = *pa; if(pb) { pb->methodB1(); pb->methodB2(); }
pa = agg2; if(pa) { pa->methodA1(); pa->methodA2(); }
pb = *pa; if(pb) { pb->methodB1(); pb->methodB2(); }
agg2 = std::move(agg1);
pa = agg2; if(pa) { pa->methodA1(); pa->methodA2(); }
pb = *pa; if(pb) { pb->methodB1(); pb->methodB2(); }
return 0;
}
#包括
#包括
#包括
#包括
命名空间动态
{
样板
T&E(T&z、施工E&E)
{如果(!z)抛出e;返回z;}
样板
施工测试与执行(施工测试与测试、施工测试与评估)
{如果(!z)抛出e;返回z;}
样板
类接口;
类骨料;
//多态不可压缩不可移动
类属性
{
公众:
财产