Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C+中的动态对象+;?_C++_C++11 - Fatal编程技术网

C++ C+中的动态对象+;?

C++ C+中的动态对象+;?,c++,c++11,C++,C++11,我意识到我很可能会得到很多“你不应该那样做,因为……”的答案,这些答案是非常受欢迎的,我可能完全同意你的推理,但我很好奇这是否可能(正如我想象的那样) < >可以定义C++中的动态/通用对象类型,在那里我可以动态创建在键值类型的系统中存储和检索的属性吗?例如: MyType myObject; std::string myStr("string1"); myObject.somethingIJustMadeUp = myStr; 请注意,somethingistmadeup显然不是MyTy

我意识到我很可能会得到很多“你不应该那样做,因为……”的答案,这些答案是非常受欢迎的,我可能完全同意你的推理,但我很好奇这是否可能(正如我想象的那样)

< >可以定义C++中的动态/通用对象类型,在那里我可以动态创建在键值类型的系统中存储和检索的属性吗?例如:

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;}
样板
类接口;
类骨料;
//多态不可压缩不可移动
类属性
{
公众:
财产