Overload -> operator to forward member-access through Proxy

前端 未结 3 754
南方客
南方客 2021-01-13 04:16

I\'m trying to wrap a Python PyObject* in an Object class. In Python, everything is a PyObject*. A list is a PyObject*, a

相关标签:
3条回答
  • 2021-01-13 05:14

    If you can change Object, you may add

    class Object {
    public:
        // other code
        const Object* operator -> () const { return this; }
        Object* operator -> () { return this; }
    };
    

    And for your Proxy

    Object operator->() { return container[key]; }
    

    So, for example

    myObj[42]->myFoo = ...
    

    is mostly equivalent to

    Proxy proxy = myObj[42];
    Object obj = proxy.operator ->();
    Object* pobj = obj.operator ->(); // so pobj = &obj;
    pobj->myFoo = ...
    
    0 讨论(0)
  • 2021-01-13 05:18

    After several hours of coaxing coliru, I have a working testcase.

    Please refer to: https://codereview.stackexchange.com/questions/75237/c11-proxy-pattern-for-supporting-obidx-someobjmember-type-acc

    Many thanks to Jarod, for supplying the correct syntax and understanding for -> overload.

    0 讨论(0)
  • 2021-01-13 05:20

    I find the Proxy class that you wrote as an example a bit confusing so i took the liberty to change it a little: Here is a simple example:

    //object with lots of members:
    class my_obj
    {
    public:
        std::string     m_text;
    
        void foo()
        {
            std::cout << m_text << std::endl;
        }
        void bar(std::string t)
        {
            m_text = t;
        }
    };
    //proxy object
    class proxy_class
    {
    private:
        friend class CustomContainer;
        my_obj* px;
    
        proxy_class(my_obj * obj_px)
            :px(obj_px)
        {
        }
        proxy_class() = delete;
        proxy_class(const proxy_class &) = delete;
        proxy_class& operator =(const proxy_class &) = delete;
    public:
    
        my_obj* operator ->()
        {
            return px;
        }
    };
    //custom container that is the only one that can return proxy objects
    class CustomContainer
    {
    public:
        std::map<std::size_t, my_obj> stuff;
    
        proxy_class     operator [](const std::size_t index)
        {
            return proxy_class(&stuff[index]);
        }
    };
    

    example usage:

    CustomContainer cc;
    cc[0]->foo();
    cc[0]->bar("hello world");
    cc[0]->foo();
    

    As a design consideration the proxy class should be create in a controlled environment so constructors are removed from preventing miss-usage.

    CustomContainer has to only return proxy_class with a reference to my_obj so it can use anything, std::map, std::vector, etc

    0 讨论(0)
提交回复
热议问题