我正在尝试包装 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/