c++ - 重载 -> 运营商通过代理转发成员访问

标签 c++ c++11 operator-overloading proxy-pattern

我正在尝试包装 Python PyObject*Object类(class)。 在 Python 中,一切都是 PyObject* . 列表是 PyObject* , 列表中的每一项本身就是一个 PyObject* . 这甚至可以是另一个列表。 等

我正在尝试允许 fooList[42] = barObj通过代理模式 ( here ) 的样式语法。

现在我已经可以正常工作了,我想扩展它以便 fooList[42]可以用作 Object .具体来说,我希望能够处理...

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

Object有很多方法,目前fooList[42].myObjMethod()将首先解决fooList[42]进入Proxy例如,说 tmpProxy , 然后尝试 tmpProxy.myObjMethod() .

这意味着我必须做

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

即手动中继每个 Object通过 Proxy 的方法, 这很丑。

我看不到任何完美的解决方案(参见上面链接的答案),但我很乐意使用:

fooList[42]->myObjMethod()

...作为一种妥协,因为 -> 可以 被重载(与不能的 . 相反)。

但是,我找不到任何关于重载 operator-> 的文档.

我最好的猜测是它必须返回一个指向某个对象的指针(比如 pObj ),并且 C++ 将调用 pObj->whatever .


下面是我尝试的实现。但是,我遇到了一个“获取对象类型的临时对象的地址”警告。

我有,在我的Object类:

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

请注意,“const 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's 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,你可以添加

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

对于您的代理

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 = ...

关于c++ - 重载 -> 运营商通过代理转发成员访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27689105/

相关文章:

c++ - GTK 应用程序 : How do I create a working indicator with Qt/C++?

c++ - 检测特定像素上的某种颜色并在检测到后发送点击的最快方法是什么?

c++ - 为什么 std::string::find() 可以处理 '\0' ?

c++ - "Polymorphic"非成员函数/运算符,我需要额外的重载吗?

c++ - 如果在重载的输出运算符函数中使用 cout 怎么办?

c++ - 无法对匿名对象使用运算符<<

c++ - 重置二维 vector 数组

c++ - std::initializer_list 的初始化

c++ - 如何在 C++ 中初始化一个局部结构对象(不能创建一个新对象作为局部变量)?

C++11 原子内存排序 - 这是宽松(释放-消费)排序的正确用法吗?