2013-04-09 16 views
7

Ho un po' di problemi con il mio costruttore. Nel mio file di intestazione dichiaro:Errore C++: tipi incompatibili nell'assegnazione di 'char *' a 'char [2]

char short_name_[2]; 
  • e altre variabili

Nel mio costruttore:

Territory(std::string name, char short_name[2], Player* owner, char units); 
void setShortName(char* short_name); 
inline const char (&getShortName() const)[2] { return short_name_; } 

Nel mio file cpp:

Territory::Territory(std::string name, char short_name[2], Player* owner, 
        char units) : name_(name), short_name_(short_name), 
        owner_(owner), units_(units) 
{ } 

Il mio errore:

Territory.cpp: In constructor ‘Territory::Territory(std::string, char*, Player*, char)’: Territory.cpp:15:33: error: incompatible types in assignment of ‘char*’ to ‘char [2]’

ho già capito che char[2] <=> char* ma non sono sicuro di come gestire questo sul mio costruttore e ottenere/setter.

+1

'Ho già capito che char [2] <=> char *' non proprio. – Rapptz

+0

ma ho pensato che il compilatore C++ fosse char [2] equivalente a char *?! Non ho davvero idea di come avviare questo costruttore e i getter correttamente ... – vicR

+1

Gli array e i puntatori sono * molto * cose diverse. Leggi la sezione 6 delle [domande frequenti su comp.lang.c (http://www.c-faq.com/); le regole in quest'area sono essenzialmente le stesse per C e C++. –

risposta

12

Gli array raw in C++ sono fastidiosi e pieni di pericoli. Questo è il motivo per cui, a meno che tu non abbia una buona ragione, dovresti usare std::vector o std::array.

Prima di tutto, come altri hanno già detto, char[2] non è lo stesso di char*, o almeno non di solito. char[2] è una matrice di dimensione 2 di char e char* è un puntatore a char. Spesso si confondono perché gli array decadono da un puntatore al primo elemento ogni volta che ne hanno bisogno. Quindi, questo funziona:

char foo[2]; 
char* bar = foo; 

Ma il contrario non lo fa:

const char* bar = "hello"; 
const char foo[6] = bar; // ERROR 

Aggiungendo alla confusione, quando si dichiara parametri di funzione, char[] è equivalente a char*. Quindi nel tuo costruttore il parametro char short_name[2] è davvero char* short_name.

Un'altra stranezza degli array è che non possono essere copiati come altri tipi (questa è una spiegazione del motivo per cui gli array nei parametri di funzione sono trattati come puntatori).Così, per esempio posso non fare qualcosa del genere:

char foo[2] = {'a', 'b'}; 
char bar[2] = foo; 

Invece devo iterare sugli elementi di foo e copiarli in bar, o usare qualche funzione che lo fa per me, come std::copy:

char foo[2] = {'a', 'b'}; 
char bar[2]; 
// std::begin and std::end are only available in C++11 
std::copy(std::begin(foo), std::end(foo), std::begin(bar)); 

Così nel costruttore è necessario copiare manualmente gli elementi di short_name in short_name_:

Territory::Territory(std::string name, char* short_name, Player* owner, 
        char units) : name_(name), owner_(owner), units_(units) 
{ 
    // Note that std::begin and std::end can *not* be used on pointers. 
    std::copy(short_name, short_name + 2, std::begin(short_name)); 
} 

Come potete vedere, tutto questo è molto fastidioso, quindi, a meno che non si abbia una buona ragione, è sufficiente utilizzare std::vector invece di matrici non elaborate (o in questo caso probabilmente std::string).

2

Quando una funzione desidera un array come argomento, ottiene invece un puntatore al primo elemento di un array. Questo puntatore non può essere usato per inizializzare un array, perché è un puntatore, non un array.

È possibile scrivere funzioni che accettano riferimenti ad array come argomenti:

void i_dont_accept_pointers(const char (array&)[2]) {} 

Il problema qui è che questo riferimento matrice non può essere utilizzata per inizializzare un altro array.

class Foo { 
    char vars[2]; 
    Foo(const char (args&)[2]) 
    : vars(args) // This will not work 
    {} 
}; 

C++ 11 introdotto std::array a eliminiate questo ed altri problemi di array. Nelle versioni precedenti, dovrai scorrere gli elementi dell'array e copiarli individualmente o usare std::copy.

Problemi correlati