2013-07-30 12 views
7

Alcune classi che incontro, hanno una doppia costruttore di stringa:efficiente stringa del costruttore

construct(const std::string& s); 
construct(const char* s); 

Avere un costruttore std::string ha il vantaggio evidente di essere in grado di passare un std::string senza c_str(). Tuttavia, se l'argomento è memorizzato in una stringa std :: anyway, c'è qualche vantaggio di avere il costruttore const char*?

In particolare:

construct(const std::string& s) : m_string(s) {} 
construct(const char* s) : m_string(s) {} 
std::string m_string; 

Sarà il secondo costruttore di essere più veloce per stringhe e char* variabili, o sarà ottimizzato via?

Domanda aggiuntiva - C++ 11 sposta la costruzione cambia qualcosa qui?

+0

In C++ 11 con la costruzione dello spostamento, è possibile utilizzare questo (come un singolo ctor per entrambi): 'construct (std :: string s): m_string (std :: move (s)) {}'. Non efficiente quanto un inoltro perfetto, ma quasi (due mosse per un temporaneo). – dyp

+0

'std :: string (" Hello There ")' Ecco perché hai un costruttore per un 'const char *', ma non sono sicuro di cosa stai chiedendo qui ... – user2485710

+0

non deve essere più veloce, è solo un secondo costruttore sovraccarico per una gestione più semplice – Alex

risposta

8

in C++ 03, o in C++ 11 ingegno se si specifica la semantica di spostamento, la conversione implicita da const char * a std::string crea una stringa temporanea, che viene quindi copiata nel membro. Questo implementa una copia extra.

In C++ 11 si può avere la temporanea spostato invece dopo il passaggio per valore:

construct(std::string s) : member(std::move(s)) {} 

L'unica altra cosa che posso pensare è la compatibilità con le altre classi che forniscono operatori di conversione.

struct String { 
    operator char const *() const; 
}; 

Poiché soltanto una conversione definita dall'utente può applicare implicitamente, la funzione std::string non riceveranno un argomento String mediante conversione attraverso char const *. Si noti, tuttavia, che con una funzione di conversione aggiuntiva a std::string e ad entrambi i costruttori, il risultato sarebbe un'ambiguità di sovraccarico.

+0

L'altro problema è (come ho notato) che non verrà sottoposto a una costruzione implicita da un valore letterale. .. è l'implementazione con std :: move() prestazioni migliori? –

+0

@KornelKisielewicz Non capisco. Niente qui sta proteggendo contro i letterali, puoi illustrare il problema? E non è necessario chiamare 'std :: move' per spostare la semantica da una temporanea. Se c'è qualche differenza, spostarsi da un temporaneo è probabilmente più lento della costruzione da un puntatore diretto. – Potatoswatter

+0

@Potatoswatter Il punto è se si usa 'construct (std :: string const & p): m_string (p)' copierete il temporaneo. – dyp

5

Se si dispone solo di char* e solo il primo costruttore, la copia può essere eseguita 2 volte. in std::string(char*) e in construct(std::string)

Mentre nel secondo costruttore il puntatore verrà copiato (è veloce) e quindi stringa copiata.

In C++ 11 buona idea è quella di creare 1 costruttore

construct(std::string s) : m_string(std::move(s)) {} 

In questo caso, se si dispone di pochi char* dati possono essere copiati in ctor stringa, ma stringa sarà temporanea, quindi sarà solo mosso in construct ctor

This code stampe "creare, copiare"
This code stampe "creare, spostare"

+0

Perché dovrebbe copiare 2 volte? – billz

+0

@billz, In string (char *) ctor e quindi in construct (stringa) – RiaD

+0

@DyP, copy & paste è male :) fisso – RiaD

Problemi correlati