Overload Operator & # 8594; to forward member access through a proxy server

I am trying to wrap Python PyObject*in a class Object. In Python, anyway PyObject*. A list is that PyObject*, and each item in the list is itself PyObject*. This could be another list. and etc.

I am trying to resolve style syntax fooList[42] = barObjusing a proxy template ( here ).

Now that I’m working, I want to expand it so that I fooList[42]can use it as Object. In particular, I want to be able to handle ...

fooList[42].myObjMethod()
fooList[42].myObjMember = ...

Objecthas many methods, and is currently fooList[42].myObjMethod()going to first resolve fooList[42]to an instance Proxy, say tmpProxy, and then try tmpProxy.myObjMethod().

That means I would have to do

void Proxy::myObjMethod(){ return wrapped_ob.myObjMethod(); }

. Object Proxy, .

(. ), :

fooList[42]->myObjMethod()

... , , → ( ., ).

operator->.

, - ( pObj), ++ pObj->whatever.


. , " Object".

Object

const Object operator[] (const Object& key)     const { 
    return Object{ PyObject_GetItem( p, key.p ) }; 
}

, 'const Object &' " Object".

class Proxy {
private:
    const Object& container;
    const Object& key;

public:
    // at this moment we don't know whether it is 'c[k] = x' or 'x = c[k]'
    Proxy( const Object& c, const Object& k ) : container{c}, key{k}
    { }

    // Rvalue
    // e.g. cout << myList[5] hits 'const Object operator[]'
    operator Object() const {
        return container[key];
    }

    // Lvalue
    // e.g. (something = ) myList[5] = foo
    const Proxy&  operator= (const Object& rhs_ob) {
        PyObject_SetItem( container.p, key.p, rhs_ob.p );
        return *this; // allow daisy-chaining a = b = c etc, that why we return const Object&
    }

    const Object* operator->() const { return &container[key]; }
    // ^ ERROR: taking the address of a temporary object of type Object
};

, myList[5]->someMemberObj = ....

myList[5] Proxy, Object ( myList). myItem.

, someProxy->fooFunc() someProxy->fooProperty myItem.fooFunc() myItem.fooProperty .

" Object".

+4
3

Object,

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

Proxy

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

,

myObj[42]->myFoo = ...

Proxy proxy = myObj[42];
Object obj = proxy.operator ->();
Object* pobj = obj.operator ->(); // so pobj = &obj;
pobj->myFoo = ...
+4

Proxy, , , : :

//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]);
    }
};

:

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

, - .

CustomContainer proxy_class my_obj, , std::map, std::vector ..

+1

Source: https://habr.com/ru/post/1569294/


All Articles