将指针类型派生到非指针类成员

时间:2010-07-09 15:47:56

标签: c++

在Rob McGregor的名为“Using C ++”的书中,有以下使用指向成员运算符的例子

class mycls
{
public:
    int member;
    int *ptr;
};

void main()
{
    mycls MyClass;

    // Derive a pointer type to the non-pointer class member
    int mycls::*member = &mycls::member;

    MyClass.ptr = new int;
    mycls* pMyClass = &MyClass;

    pMyClass->*member = 5;
    *MyClass.ptr = 10;

    cout << "pMyClass->*member = " << pMyClass->*member << "\n"; // pMyClass->*member = 5
    cout << "MyClass.*member = " << MyClass.*member << "\n"; // MyClass.*member = 5
    cout << "*MyClass.ptr = " << *MyClass.ptr << "\n"; // *MyClass.ptr = 10
    cout << "*pMyClass->ptr = " << *pMyClass->ptr << "\n"; // *pMyClass->ptr = 10

    delete MyClass.ptr;
}

在这个例子中,我不明白为什么成员变量mycls::member可能成为(猜测)这行代码之后的指针:

int mycls::*member = &mycls::member; 

这是做什么的?

3 个答案:

答案 0 :(得分:6)

假设您有一个局部变量:

int member;

您可以使用以下命令指向它:

int *ptr = &member;

要获取指向成员语法的指针,我们只需将mycls::附加到适当的位置:

int mycls::*member = &mycls::member;

通过一个示例可以更清楚地显示指针如何在类的正确类型的任何成员之间切换:

class C
{
public:
    int a;
    int b;
};

void main()
{
    // make pointer to member, initially pointing to a
    int C::*ptrToMember = &C::a;

    C x;
    C *ptrToObj = &x; // make pointer to object x

    ptrToObj->*ptrToMember = 2; // store in a;

    ptrToMember = &C::b; // change pointer to b

    ptrToObj->*ptrToMember = 3; // store in b;
}

注意我们在创建a类型的对象之前如何创建指向成员C的指针。它只是指向成员的指针,而不是指向特定对象成员的指针。在“商店”步骤中,我们必须说明哪个对象以及哪个成员。

<强>更新

在评论中,OP询问是否相同:

int *ptr = &(ptrToObj->a);

不,不是。这是指向内存中任何位置的任何int的指针。

理解这一点的最简单方法是从技术上考虑它的含义。 “指针”是内存中的绝对位置:在哪里查找对象。 “指向成员的指针”是相对位置,有时称为偏移:在外部对象的存储中中找到对象的位置。在内部,它们只是数字。必须将指向成员的指针添加到普通指针以生成另一个指针。

因此,如果你有一个指向对象的指针(int是一个对象!),你可以用它来改变存储在内存中绝对位置的内容:

*ptr = 123;

但是如果你有一个指向成员的指针,它就不是一个内存位置。它是一个偏移量,一个要添加到内存位置的量。你不能单独使用它。您必须将其“添加”到对象指针:

ptrToObj->*ptrToMember = 132;

这意味着:转到内存ptrToObj中的位置,然后沿距离ptrToMember移动。

答案 1 :(得分:2)

他打电话给班级成员member和指向成员的指针member,使问题混乱。是否重命名这些帮助?

类别:

class SampleClass
{
public:
    int m_data;
    int* m_pointer;
};

用法:

int main()
{
    SampleClass sample;

    // Derive a pointer type to the non-pointer class member
    int SampleClass::*pointerToMember = &SampleClass::m_data;

    sample.m_pointer = new int;
    SampleClass* pSample = &sample;

    pSample->*pointerToMember = 5;
    *sample.m_pointer = 10;

    // pSample->*pointerToMember = 5
    cout << "pSample->*pointerToMember = "
         << pSample->*pointerToMember << "\n";

    // sample.*pointerToMember = 5
    cout << "sample.*pointerToMember = "
         << sample.*pointerToMember << "\n";

    // *sample.m_pointer = 10
    cout << "*sample.m_pointer = "
         << *sample.m_pointer << "\n";

    // *pSample->m_pointer = 10
    cout << "*pSample->m_pointer = "
         << *pSample->m_pointer << "\n";

    delete sample.m_pointer;
}

[Code]

编辑:重新“我仍然很清楚int *ptr = &(ptrToObj->a);是否与使用指向成员的指针相同”:

它不是指向成员的指针。它只是一个正常的指向内存的指针,恰好在一个对象中。

您可以在此处查看使用的语法:

类别:

class C
{
public:
    int a;
    int b;
};

用法:

int main()
{
    // make pointer to member, initially pointing to a
    int C::*ptrToMember = &C::a;

    C x = {10, 11};
    C *ptrToObj = &x; // make pointer to object x

    cout << "a initial value: " << ptrToObj->*ptrToMember << endl;

    ptrToObj->*ptrToMember = 2; // store in a;

    cout << "a after change: " << ptrToObj->*ptrToMember << endl;

    ptrToMember = &C::b; // change pointer to b

    cout << "b initial value: " << ptrToObj->*ptrToMember << endl;

    ptrToObj->*ptrToMember = 3; // store in b;

    cout << "b after change: " << ptrToObj->*ptrToMember << endl;


    int* ptr = &(ptrToObj->a);
    cout << "ptr to a: " << *ptr << endl;

    ptr = &(ptrToObj->b);
    cout << "ptr to b: " << *ptr << endl;
}

[Code]

答案 2 :(得分:0)

声明中的星号字符是该类型的一部分。

您的声明分解为

输入:int mycls::*

变量名称:member

Initialiser:= &mycls::member

这个新变量member点是指向mycls中的int的成员指针。它不必指向mycls::member