Contesto: Sono in un ambiente con codice grande in cui l'ordine non definito in cui vengono eseguiti i costruttori globali è problematico. Quindi ho una classe personalizzata progettata per ritardare l'inizializzazione fino al primo utilizzo. Tutta la sua magia si verifica all'interno delle sue funzioni operatore * e operatore->; sono l'unica cosa definita. Memorizza anche alcuni stati al suo interno, per rendere disponibile la funzione di inizializzazione automatica. Questo stato deve, ovviamente, essere POD, in modo che l'intera classe sia POD, in modo che possa essere completamente impostata prima che il codice di chiunque inizi a funzionare, in modo che tutto il codice possa usare tutti i globali ovunque, senza il timore che i globali non si nascondano " è stato ancora istituito.C++ 11: un operatore di assegnazione impedisce a un tipo di essere POD e pertanto viene inizializzato a livello globale?
Un po 'di tempo fa qualcuno ha aggiunto un operatore di assegnazione privato, mai definito, in modo che il tipo non sarebbe mai stato assegnato a (non è progettato per mai cambiare comunque). Ora qualcun altro sta dicendo che la lezione è rotta perché non è POD. Se invece di essere dichiarato-ma-non-definito, lo dichiaro come "= delete", sto pensando che sia in qualche modo migliore. E infatti, con questa modifica, std :: is_pod <> :: value restituisce true per il tipo.
Ma come un operatore di assegnazione impedisce a un tipo di essere POD? Pensavo che i requisiti fossero solo che doveva avere solo membri di dati pubblici, nessun metodo virtuale e nessun costruttore o distruttore.
E più al punto per la mia situazione: la presenza di un operatore di assegnazione non definito impedisce alla classe di essere inizializzata al momento di inizializzazione globale, insieme a tutti gli altri POD globali?
esempio ridotto:
struct LazyString {
const char *c_str;
bool has_been_inited;
string *lazy_str_do_not_use_directly;
string &operator*() { return *get(); }
string *operator->() { return get(); }
private:
string *get() {
// The real code uses a mutex, of course, to be thread-safe.
if (!has_been_inited) {
lazy_str_do_not_use_directly = new string(c_str);
has_been_inited = true;
}
return lazy_str_do_not_use_directly;
}
// Does this make the class non-POD?
// If so, does that mean that global variables of this type
// will not be initialized at global-initialization time, that wonderful
// moment in time where no code has yet been run?
void operator=(const LazyString&);
// If I do this instead, it breaks C++03 compatibility, but is this somehow better?
void operator=(const LazyString&) = delete;
};
LazyString lazy = { "lazy" };
int main(int argc, char *argv[]) {
std::cout << *lazy;
}
Produrre la gestione della memoria del proprio heap non è quasi mai una buona idea. Perché pensi di aver bisogno di questo? (intendevi implementare s.th. come [copy-on-write] (http://stackoverflow.com/questions/12199710/legality-of-cow-stdstring-implementation-in-c11)) –
Sei confondendo POD-ness e inizializzazione statica. Né dipende dall'altra. –
Poiché tutti i membri dati sono visibili pubblicamente, tale dichiarazione costituisce un POD, sì. ** NOTA: ** Avrai effetti collaterali indesiderati riguardo alla 'nuova stringa (c_str);' nella tua _lazy initialization_, quando copi/assegni questo tipo di POD. –