指向成员函数的指针

时间:2016-11-07 22:30:27

标签: c++ c++11 rvalue pointer-to-member

有结构

Private Sub test1()
    'This throws an error
    Dim ws As Worksheet

    Set ws = ThisWorkbook.Sheets.Add
    NameWS rootname:="mysheet", ws:=ws
    'ws.Activate
    If Sheet1.CheckBox1.Value = True Then MsgBox "true" Else MsgBox "false"

End Sub

Private Sub test2()
    ' This works fine
    Dim ws As Worksheet

    Set ws = ThisWorkbook.Sheets.Add
    NameWS rootname:="mysheet", ws:=ws
    ws.Activate
    If Sheet1.CheckBox1.Value = True Then MsgBox "true" Else MsgBox "false"

End Sub


Private Sub NameWS(rootname As String, ws As Worksheet)
    ' This sub tries to name the WS as rootname, if it fails, it increments a counter in the name.

    Dim ctr As Long
    ctr = 0

    On Error GoTo Err1:
    ws.Name = rootname
    Exit Sub

BaseNameTaken:
    ctr = ctr + 1
    On Error GoTo Err1:
    ws.Name = rootname & " (" & ctr & ")"
    ' If execution makes it to here it means that a valid name has been found

    On Error GoTo 0
    Exit Sub

Err1:
    If ctr > 99 Then Resume Fail ' Just to ensure we haven't created an infinite loop
    Resume BaseNameTaken

Fail:
    ' Leave sub. Inability to name WS is not a critical error.
    MsgBox "Failed to name worksheet after " & ctr & " tries. Excel default name used."

End Sub

我可以通过将指向成员数据的指针作为参数传递给函数来动态返回成员数据。 e.g

struct Person{
    Person( int i , int g):id(i),age(g){};
    int id;
    int age;
};

并使用

进行调用
int extract( Person * p , int Person::* param)
{   
    return p ->*param;
}

但我的问题是,为什么这有用?我们正在传递Person *p = new Person (10 , 20 ); cout << extract(p , &Person::id )<< endl; 基本内存,但Person是一个违反定义的r值。

我感谢所有对我可能对主题的误解的解释/澄清。 感谢。

1 个答案:

答案 0 :(得分:6)

C ++中成员的指针可以理解为“偏移”定义。虽然当你有虚拟功能等时会出现一些复杂情况,但在你的情况下这已经足够了。

所以,基本上你的代码就像(如果我们将数据类型转换为“原始”数据)

int extract(void *p, int offset)
{
    return *((int*)(p+offset));
}

(从技术上讲,上面的代码不是编译的,因为void *指针不能用于附加表达式,因为编译器不知道指针的大小,但是现在让我们忽略它。)< / p>

当你调用它时,代码看起来像

extract(p, __offsetof(Person, id));

其中__offsetof是伪运算符,编译器将在编译时计算它。

你可以看到这里没有魔力。 C ++可以帮助您的是,偏移量是以特殊数据类型保护的,因此不允许您更改其内部,从而避免分离。

有关C / C ++指针转换和算术的其他信息

上面的代码对于C / C ++用户来说是非常基本的,虽然它不是C ++专业人员想要看到的形式(应使用static_castreinterpret_cast而不是C stype转换。)< / p>

我看到问题提问者要求进一步解释有关C / C ++指针算法的问题,这有点偏离主题,因为它与这里提出的问题无关,所以我提供了一些关于这个主题的进一步参考。 / p>

Pointer Arithmetic

http://www.technoplaza.net/programming/lesson9p2.php

http://www.informit.com/articles/article.aspx?p=686170&seqNum=8