I puntatori incrementali sono C ++ idiomatico, perché la semantica del puntatore riflette un aspetto fondamentale della filosofia di progettazione alla base della libreria standard C ++ (basata su STL )
Il concetto importante qui è che l'STL è progettato attorno a contenitori, algoritmi e iteratori. I puntatori sono semplicemente iteratori .
Ovviamente, la possibilità di incrementare (o aggiungere / sottrarre da) i puntatori torna a C. Un sacco di algoritmi di manipolazione della C-string può essere scritto semplicemente usando l'aritmetica del puntatore. Considera il seguente codice:
char string1[4] = "abc";
char string2[4];
char* src = string1;
char* dest = string2;
while ((*dest++ = *src++));
Questo codice utilizza l'aritmetica del puntatore per copiare una C-string con terminazione null. Il ciclo termina automaticamente quando incontra il null.
Con C ++, la semantica dei puntatori è generalizzata al concetto di iteratori . La maggior parte dei contenitori C ++ standard fornisce iteratori, a cui è possibile accedere tramite le funzioni membro begin
e end
. Gli iteratori si comportano come dei puntatori, in quanto possono essere incrementati, dereferenziati e talvolta decrementati o avanzati.
Per ripetere su std::string
, dovremmo dire:
std::string s = "abcdef";
std::string::iterator it = s.begin();
for (; it != s.end(); ++it) std::cout << *it;
Aumentiamo l'iteratore proprio come avremmo incrementato un puntatore a una semplice stringa C. La ragione per cui questo concetto è potente è che puoi utilizzare i modelli per scrivere funzioni che funzioneranno per qualsiasi tipo di iteratore che soddisfi i requisiti di concetto necessari. E questo è il potere dell'STL:
std::string s1 = "abcdef";
std::vector<char> buf;
std::copy(s1.begin(), s1.end(), std::back_inserter(buf));
Questo codice copia una stringa in un vettore. La funzione copy
è un modello che funziona con qualsiasi iteratore che supporta l'incremento (che include semplici puntatori). Potremmo usare la stessa funzione copy
su una semplice stringa C:
const char* s1 = "abcdef";
std::vector<char> buf;
std::copy(s1, s1 + std::strlen(s1), std::back_inserter(buf));
Potremmo usare copy
su un std::map
o un std::set
o qualsiasi contenitore personalizzato che supporti gli iteratori.
Nota che i puntatori sono un tipo specifico di iteratore: iteratore di accesso casuale , il che significa che supportano l'incremento, il decremento e l'avanzamento con l'operatore +
e -
. Altri tipi di iteratore supportano solo un sottoinsieme di semantica del puntatore: un iteratore bidirezionale supporta almeno l'incremento e il decremento; un forward iterator supporta almeno un incremento. (Tutti i tipi di iteratore supportano il dereferenziamento.) La funzione copy
richiede un iteratore che almeno supporti l'incremento.
Puoi leggere i diversi concetti di iteratore qui .
Quindi, i puntatori incrementali sono un modo idiatico di C ++ per scorrere su un C-array, o accedere a elementi / offset in un array C.