2013-07-19 43 views
3

當使用指針到成員(AKA點星級或箭頭星)訪問類的成員,我們可以使用下面的語法:如何在使用指針到成員時通過範圍解析操作員獲取類成員的地址?

A * pa; 
int A::*ptm2 = &A::n; 
std::cout << "pa->*ptm: " << pa->*ptm << '\n'; 

我的問題是如何做的&A::n聲明的工作?

在上面的例子中n是一個變量。如果不是成員變量,n是一個函數(並且我們定義了一個指向成員函數的指針而不是指向成員的指針),但我可能會推斷,因爲類的函數可以是有效的靜態的見Nemo的評論),我們可以通過&A::some_function找到一個班級的功能地址。但是,我們如何通過類範圍解析來獲取非靜態類成員的地址?當我打印&A::n的值時,這更令人困惑,因爲輸出僅僅是1

+3

成員變量,它是在對象實例的開始偏移。 ' - > *'然後大致相當於僅添加其LHS(實例)和RHS(偏移)部分。 – syam

+0

@syam這就是我的想法。但是,如果我爲多個成員變量輸出'&A :: member_variable',我會爲它們全部得到'1'。 – user2141130

+3

一個類的函數不一定是「有效靜態的」;考慮虛擬函數,多重繼承等等......「指向成員」的內部表示可能變得非常複雜。某些實現使用最多16個字節(請參閱http://lazarenko.me/2013/04/28/cc-pointers-to-member-functions/) – Nemo

回答

2

當您聲明一個指向成員數據的指針時,它不受任何特定實例限制。如果您想知道給定實例的數據成員的地址,則需要在執行.*->*後獲取結果的地址。例如:

#include <stdio.h> 

struct A 
{ 
    int n; 
}; 

int main() 
{ 
    A a = {42}; 
    A aa = {55}; 
    int A::*ptm = &A::n; 
    printf("a.*ptm: %p\n", (void *)&(a.*ptm)); 
    printf("aa.*ptm: %p\n", (void *)&(aa.*ptm)); 
} 

版畫作爲一種可能的輸出:

a.*ptm: 0xbfbe268c 
aa.*ptm: 0xbfbe2688