如何获得私有类成员的偏移量? 我有一个C++类(脚本< /代码>),用python类型包装: struct PyScenario { PyObject_HEAD Scenario scen; };

如何获得私有类成员的偏移量? 我有一个C++类(脚本< /代码>),用python类型包装: struct PyScenario { PyObject_HEAD Scenario scen; };,python,c++,python-3.x,c++11,c++14,Python,C++,Python 3.x,C++11,C++14,我想在不使用显式getter/setter函数的情况下,向Python脚本公开场景的一些私有成员: static PyMemberDef scenarioMembers[] { { (char *)"a", T_DOUBLE, offsetof(PyScenario, scen._a), "The a" }, { (char *)"b", T_INT, offsetof(PyScenario,

我想在不使用显式getter/setter函数的情况下,向Python脚本公开
场景
的一些私有成员:

static PyMemberDef scenarioMembers[] {
    {
        (char *)"a",
        T_DOUBLE, offsetof(PyScenario, scen._a),
        "The a"
    },
    {
        (char *)"b",
        T_INT, offsetof(PyScenario, scen._b),
        "The b"
    },
    NULL
};
不幸的是,当我编译上面的代码时,我得到了一个错误,比如:
“双场景::_a”在这个上下文中是私有的

我不想将
\u a
\u b
公开,因此我尝试声明
场景的
PyMemberDef
朋友

class Scenario {
#ifdef PY_MAJOR_VERSION
    friend   struct PyMemberDef;
#endif
private:
    double   _a;
    int      _b;
    ....
};

不幸的是,这没有帮助。。。正确的方法是什么?

您所做的基本问题是(大概)全局变量的初始值设定项位于全局上下文中。初始值设定项既不是类的一部分,也不是函数的组件,因此它不能是任何东西的朋友

您应该将变量设置为函数-
静态
变量。并且包含变量的函数可以是类的朋友

PyMemberDef *PyMemberInitializers()
{
    static PyMemberDef scenarioMembers[] {
        {
            (char *)"a",
            T_DOUBLE, offsetof(PyScenario, scen._a),
            "The a"
        },
        {
            (char *)"b",
            T_INT, offsetof(PyScenario, scen._b),
            "The b"
        },
        NULL
    };

    return scenarioMembers;
}

“我想向Python脚本公开场景的一些私有成员,而不使用显式的getter/setter函数:”-为什么?为什么不想使用getter函数从对象获取数据?这对我来说毫无意义。@JesperJuhl:大概他们是想利用
PyMemberDef
为简单值生成访问器的能力,而不是编写自定义函数来使用更复杂/功能更强大的
PyGetSetDef
访问器。CPython基本上是C++盲的,所以它不能直接使用成员函数,这意味着它们必须编写包装来调用成员函数。谢谢,@ShadowRanger。这是正确的-我想要直接访问标准标量类型字段的速度和简单性,是的。@MikhailT.:我会注意到,虽然编写
GetSet
描述符显然比
成员
更复杂,但在速度方面,它们应该大致相当
Member
s只是为您编写访问器函数的描述符的特例;一般来说,它们的速度并不快(可能是由于使用共享热代码路径的意外情况除外)。好吧,这可能会起作用,但从我使用的C++11开始,类型已经可以是“朋友”——不仅仅是函数/类。。。我误读了吗?@MikhailT.:“类型已经可以是“朋友”——不仅仅是函数/类……”类是类型。不,您不能声明
int
朋友。我的观点是,友谊和访问是关于访问成员的代码的位置。带括号的init列表中的代码不会获得访问类型成员的任何附加权限。函数内部的代码获得函数的访问权限。类定义中的代码获得类的访问权限。带大括号的init列表中的代码拥有该代码所在位置的访问权限,仅此而已。但是,第4部分的意思是什么?我想,通过将
PyMemberDef
声明为朋友,我完全允许我尝试的用法…@MikhailT.:
friend T
仅仅是
友元类/struct/union T的简写,如该节中明确说明。我的观点是:如果
X
Y
的朋友,这意味着
X
中的成员和定义可以访问
Y
的隐私。应用于
X
类型的对象的初始值设定项不在
X
范围内,因此不计算在内。