2010-06-03 18 views
5

C'è un modo per sapere se un oggetto è un oggetto const o un oggetto regolare, ad esempio, si consideri la seguente classe dioggetto const e costruttore const

class String 
{ 
    String(const char* str); 
}; 

se l'utente creare un oggetto const da String allora non c'è motivo per copiare la stringa nativa passata e che, poiché non effettuerà alcuna manipolazione su di essa, l'unica cosa che farà sarà ottenere la dimensione della stringa, la ricerca di stringhe e altre funzioni che non cambieranno la stringa.

+5

Non c'è modo di sapere. Infatti, 'const' si applica solo una volta che l'oggetto è inizializzato (il costruttore termina) e si arresta quando viene immesso il distruttore. – GManNickG

risposta

8

C'è una buona ragione per copiare - non si può sapere che la durata del const char * è uguale a quella dell'oggetto String. E no, non c'è modo di sapere che stai costruendo un oggetto const.

2

Sfortunatamente, il C++ non fornisce un modo per fare ciò che si sta tentando. Il semplice passaggio di un const char * non garantisce la durata della memoria puntata. Valuta:

char * a = new char[10]; 
char const *b = a; 
String c (b); 
delete[] a; 
// c is now broken 
2

Non c'è modo per voi di sapere. È possibile scrivere una classe che interagisca strettamente con String e che crei una stringa costante che punta a un buffer esterno (rendendo privato il costruttore corrispondente e rendendo la classe interattiva una classe nidificata o un amico di String).

Se tutto ciò di cui si preoccupa è eseguire la gestione dinamica della memoria su una stringa costante potenzialmente piccola, è possibile implementare l'Ottimizzazione stringa piccola (anche Ottimizzazione piccolo oggetto/buffer). Funziona con un buffer incorporato nella classe della stringa e copiando ciascuna stringa fino a una dimensione predefinita in quel buffer e ogni stringa più grande rispetto a una memoria allocata dinamicamente (la stessa tecnica viene utilizzata da boost::function per la memorizzazione di oggetti funzione di piccole dimensioni) .

class String { 
    union { 
    char *dynamicptr; 
    char buffer[16]; 
    }; 
    bool isDynamic; 
}; 

esistono tecniche intelligenti per memorizzare anche la lunghezza della stringa incorporato nel buffer stesso (memorizzazione sua lunghezza buffer[15] e inganni simili).

0

Quello che stai cercando è fondamentalmente una stringa COW (copia su scrittura). Tali cose sono del tutto possibili, ma farle funzionare bene è in qualche modo non banale. In un ambiente con multithreading, ottenere buone prestazioni può andare oltre il non banale nel range decisamente difficile.

1

È possibile utilizzare const_string per fare ciò che si sta cercando. Comunque, anche con const string devi "dirlo" che la stringa non ha bisogno di essere copiata.

const char* foo = "c-string"; 
boost::const_string bar(foo); // will copy foo 
boost::const_string baz(boost::ref(foo)); // assumes foo will always be a valid pointer. 
1

se l'utente creare un oggetto const da String allora non c'è motivo di copiare la stringa nativa passato e che, poiché egli non farà alcuna manipolazione su di esso, l'unica cosa che farà è ottenere dimensioni stringa , ricerca stringa e altre funzioni che non cambieranno la stringa.

Oh sì, c'è. Solo che è passato come const non significa che in realtà è const al di fuori della chiamata del costruttore, e in particolare non significa che non verrà distrutto mentre l'oggetto stringa esiste ancora. La parola chiave const per un argomento di funzione significa solo che la funzione non la modificherà o la eliminerà (provare a implementare una funzione che modifica un argomento const comporterà un errore del compilatore), ma non c'è modo per la funzione di sapere cosa succede fuori .