2010-03-05 16 views
6

Sono bloccato in un problema di stampa. Apprezzerei se posso ottenere un aiuto qui: Nel codice qui sotto, posso vedere la famiglia di caratteri di essere spostato correttamente in first printf(), ma se lo imposto a variabile, ottengo solo una stringa vuota. Come posso inserirlo in una variabile e avere i valori giusti? Non voglio semplicemente digitare 'font.family(). Family(). Stringa(). Utf8(). Data()' ovunque?domanda printf con variabile const char *

ho fatto questo con lo stesso metodo:

void myMethod() { 
     const char* fontFamily = font.family().family().string().utf8().data(); 
     // get displayed correctly 
     printf ("drawText1 %s \n", font.family().family().string().utf8().data()); 
     // get an empty string 
     printf ("drawText2 %s \n", fontFamily); 
} 

E la firma del 'dei dati()' è

class CString { 
public: 
    CString() { } 
    CString(const char*); 
    CString(const char*, unsigned length); 
    CString(CStringBuffer* buffer) : m_buffer(buffer) { } 
    static CString newUninitialized(size_t length, char*& characterBuffer); 

    const char* data() const; 
//... 

} 

La firma del utf8() è

class String { 
CString utf8() const; 
} 

Grazie.

+0

Che cos'è questa libreria di font? Il C++ non ha niente del genere. Forse prova a includere il tipo restituito da 'data()'. In una nota a margine, c'è qualche ragione per non usare 'std :: string' /' std :: cout'? – GManNickG

+1

Sarebbe utile conoscere la firma del metodo '.data()'. – pioto

+0

E family.string() restituisce un oggetto temporaneo di tipo CString? –

risposta

4

Qualcosa nella catena di font.family().family().string().utf8().data() restituisce un oggetto temporaneo. Nel primo printf, l'oggetto temporaneo non esce dall'ambito finché non viene restituito printf. Nel secondo printf, il temporaneo è stato distrutto dopo l'assegnazione del puntatore e il puntatore non è più valido. Stai vedendo un classico esempio di "comportamento indefinito".

Ci sono due modi per risolvere questo problema. O fare una copia dei dati prima che il temporaneo venga distrutto, o fare un riferimento al temporaneo. La copia è probabilmente più semplice e chiara, purché la classe abbia un operatore di copia. Supponendo che utf8() genera una temporanea CString, questo sarebbe

CString fontFamily = font.family().family().string().utf8(); 
printf ("drawText2 %s \n", fontFamily.data()); 
+0

Questo è sbagliato. I provvisori sono garantiti per tutto il tempo necessario (più o meno). –

+0

È garantito un riferimento a un temporaneo, ma un puntatore a un membro di dati interno? Penso di no. –

+0

Non ci sono puntatori nel codice quotato. I puntatori "interni" saranno presi in considerazione dal meccanismo di costruzione/distruzione del C++. –

0

La chiamata a data() (supponendo che viene chiamato uno std :: string) non necessariamente restituire una stringa con terminazione null. Quasi certamente vuoi c_str(), che è definito per farlo.

1

Si sta memorizzando nella cache un puntatore che risiede nel temporaneo restituito da utf8() (come hanno sostenuto Mark e Neil). È necessario modificare fontFamily in uno CString o const CString & per mantenere il risultato da utf8() nell'ambito.

+0

Grazie. Questo risolve il problema. – michael