2010-05-06 21 views
7

Ho letto dei suggerimenti per i membri della classe, ma non li ho mai visti in nessuna applicazione pratica. Qualcuno può spiegare quali sono i casi d'uso di tali indicatori? È davvero necessario avere questi suggerimenti?A cosa servono i puntatori ai membri della classe?

Es.

class abc 
{ 
public: 
    int a; 
    abc(int val) { a = val; } 
}; 

int main() 
{ 
    int abc::*data; 
    abc obj(5); 

    data = &abc::a; 

    cout << "Value of a is " << obj.*data << endl; 

    return 0; 
} 

In quanto sopra ad es. perché il valore di "a" è acceduto in questo modo? Qual è il vantaggio di usare i puntatori ai membri della classe?

risposta

9

Il più grande vantaggio di un membro di puntatore-a-o il puntatore-a-membro-funzione è che si

  • non c'è bisogno di legarsi a una specifica istanza subito
  • non hanno bisogno per inserire eventuali restrizioni sui nomi dei membri, solo il tipo deve corrispondere.

Questo può essere utilizzato per es. call-back o algoritmi astratte:

std::map<int,int> m; 
m.insert(std::make_pair(1,2)); 
m.insert(std::make_pair(3,4)); 
m.insert(std::make_pair(5,6)); 
std::ptrdiff_t s = 
    std::count_if(m.begin(), m.end(), 
        boost::bind(&std::map<int,int>::value_type::first, _1) > 2); 
std::cout << s << std::endl; // 2 

noti che Boost.Bind, Boost.Function ei loro equivalenti TR1 già incapsulare che bene per voi. In una certa misura lo standard attuale include anche strumenti come std::mem_fun in <functional>.

+0

'std :: mem_fun()' et al. contare su pointer-to-member. – wilhelmtell

+0

Sì, ma incapsulano l'utilizzo: raramente ho bisogno di dichiarare i pointer-to-member da un po 'di tempo. –

+0

Per la chiarezza della dimostrazione, probabilmente avrei usato 'map :: operator []': la combinazione 'insert' e' make_pair' è così prolissa: p Buona risposta grazie :) –

2

Se avete usato MFC, si vedrà puntatori al concetto di funzione di membro viene utilizzato pesantemente (internamente)

DECLARE_MESSAGE_MAP, BEGIN_MESSAGE_MAP, END_MESSAGE_MAP Vedi Message Maps

0

La domanda che mi immagino è: "che cosa fa puntatore ai dati dei membri si aggiunge un semplice puntatore ai dati? " e l'unica risposta che riesco a pensare è un livello di significato esplicito: stiamo puntando ai dati in questa classe.

Ora posso vedere un po 'di valore in quella che effettivamente è una documentazione aggiuntiva di intenti. Un esempio che ho visto potrebbe essere piuttosto potente quando la nostra "classe" è in realtà una struttura C legacy. Ora non abbiamo metodi locali di quella struttura, quindi avere alcuni puntatori che sono esplicitamente associati a quella struttura potrebbe rendere il nostro codice più chiaro.

+1

Se si specifica sia l'istanza di classe che la variabile, si ha un puntatore normale (l'indirizzo è completamente specificato). È quando si specifica la variabile ma non l'istanza della classe che si ottiene un puntatore-membro, che è praticamente l'offset dall'inizio della istanza in cui è memorizzata quella variabile. Sono sufficienti informazioni per uscire e accedere alla variabile in qualsiasi istanza della classe. –

0

puntatore-a-membro è, come tutte le funzioni C++, solo zucchero sintattico per qualcosa che si potrebbe già aver fatto in puro C.

puntatori-a-membro variabile sono abbastanza semplici. Un caso d'uso è se si desidera scrivere una funzione (modello) che possa ordinare una matrice di strutture in base a qualsiasi campo. Passando da un puntatore a membro, è possibile recuperare il campo specificato di qualsiasi istanza della struttura senza dover codificare il campo. Naturalmente un funtore che accetta un puntatore di struttura e restituisce il valore del campo potrebbe invece essere stato utilizzato.

La funzione di puntatori a membro è un po 'più complicata. A prima vista, sono proprio come normali puntatori di funzioni che sanno come passare il puntatore nascosto "questo". Ma le funzioni virtuali rendono piuttosto semplice una semplice idea.

E le classi di base virtuali rendono tutti i pointer-to-member estremamente complicati. Non è qualcosa che vorresti codificare tu stesso usando semplici costrutti C. Ma i casi complessi sono rari.

Problemi correlati