2010-10-15 24 views
5

ho un programma e molti dei suoi classi hanno alcuni operatori e metodi con la parola chiave const, come i seguenti:metodi const e no const in C++?

operator const char*() const; 
operator char*(); 
void Save(const char *name) const; 
void Load(const char *name); 

Primo: ciò significa const alla fine della dichiarazione metodo ?, è così il lo stesso come metterlo all'inizio?

Secondo: perché sarebbe necessaria una versione const e una versione const dell'operatore()?

Grazie in anticipo.

risposta

2

'const' alla fine dice al compilatore che questo metodo non cambia nessuna variabile membro - che è sicuro chiamare questo metodo su istanze const. Quindi, Save potrebbe essere chiamato su un'istanza const, poiché non cambierà quell'istanza. Caricare d'altra parte, cambierà l'istanza quindi non può essere utilizzato su istanze const.

La versione const di operator() restituisce un puntatore const, garantendo che il buffer passato non cambierà. Presumibilmente è un puntatore in una variabile di istanza della classe. Per le istanze non const, l'altro operatore() restituisce un puntatore non const. Dovrebbe essere un puntatore a una memoria che, anche se scritta, non cambierebbe il contenuto dell'istanza.

Inoltre, cercare la parola chiave 'mutabile' a volte. Capire ciò ti aiuterà a capire questa idea di correttezza.

2

Costanza funzione membro. Significa che la funzione non può (*) modificare nessuna delle variabili membro. È come mettere un const davanti a tutte le variabili membro per questa chiamata a una funzione. È una buona garanzia per i clienti della tua classe e può anche aiutare nell'ottimizzazione del compilatore.

(*) - vedere anche la parola chiave mutabile.

8

Primo: cosa significa const alla fine della dichiarazione del metodo ?, è lo stesso come metterlo all'inizio?

No. Un const al termine significa che il metodo può essere chiamato su oggetti che sono dichiarate const. A const all'inizio significa che il valore restituito è const.

Secondo: perché è necessaria una versione const e una versione const dell'operatore()?

La versione non const restituisce un char* che non è const. Modificando questo char* si potrebbe quindi modificare l'oggetto (supponendo che lo char* sia membro dell'oggetto).

Poiché questo non è consentito per const oggetti, c'è un sovraccarico di operator() per oggetti const, in modo che un const char* viene restituito, quindi l'oggetto non può essere modificata attraverso di essa.

+1

Ok, rispondo, la tua è molto più chiara. –

1

L'immissione di const alla fine di una dichiarazione di metodo indica che l'oggetto stesso, o this, è const anziché il tipo restituito.

C++ consente di sovraccaricare i metodi su const per motivi complessi. Non c'è abbastanza spazio per entrare nei dettagli qui. Ma qui ci sono un paio di brevi.

  • Occasionalmente c'è valore o necessità piatta, di avere un metodo di comportarsi in modo diverso quando viene chiamato da un tipo const. L'esempio più semplice è quando si desidera restituire un valore const da un metodo const e un valore non const da un metodo normale.
  • Se o no this è const cambia radicalmente l'associazione del metodo interno. Al punto che sarebbe essenzialmente diventato due diversi corpi di metodo. Quindi ha senso dividerlo in 2 metodi diversi.
0
  1. Const all'inizio si applica al valore restituito. Const alla fine si applica al metodo stesso. Quando dichiari un metodo come "const", stai dicendo che non hai intenzione di modificare nessuna delle variabili membro della classe nel metodo. Il compilatore eseguirà anche alcuni controlli di base per assicurarsi che il metodo non modifichi le variabili membro. Il const nel valore di ritorno impedisce al chiamante di modificare il valore che viene restituito. Questo può essere utile quando si restituiscono puntatori o riferimenti a dati gestiti dalla classe. Questo è spesso fatto per evitare il ritorno di copie di dati complessi che potrebbero essere costosi in fase di esecuzione.

  2. La ragione per cui si hanno due operatori diversi è che la versione "const" restituisce un puntatore const a quelli che sono probabilmente i dati interni alla classe. Se l'istanza della classe è const, allora è probabile che i dati restituiti siano anche const. La versione "non-const" fornisce solo un metodo che restituisce un valore di ritorno modificabile quando il chiamante ha un'istanza non-const della classe.

1

Una nota in aggiunta alle altre risposte: non c'è operator() nell'esempio.

operator const char*() const; 
operator char*(); 

sono operatori di conversione, il che significa che gli oggetti della classe possono essere implicitamente convertiti in stringhe in stile C, come

void f(const MyClass& x, MyClass& y) { 
    const char* x_str = x; 
    char* y_str = y; 
} 

Una dichiarazione e l'utilizzo di operator(), che significa che è possibile utilizzare un oggetto del tipo di classe un po 'come una funzione, sarebbe simile:

class MyClass { 
public: 
    const char* operator() (int x, int y) const; 
    // ... 
}; 

void g(const MyClass& obj) { 
    const char* result = obj(3, 4); 
} 
1

Se siete alla ricerca di una grande risorsa su C++ (compresi suggerimenti sull'utilizzo di 0.123.correttamente) prova "Effective C++".

Un sito utili su: JRiddel.org

In C++ quando si dichiara un metodo const mettendolo dopo la firma del metodo che si sta affermando che "Questo metodo non modificare alcuna mutable variabili non di istanza nell'oggetto esso viene chiamato. "

Il const prima del valore restituito (ad esempio const in: operator const char*...") dichiara che restituisce solo un puntatore variabile a const char*. (Non è possibile modificare il contenuto di char* ma è possibile riassegnare il puntatore.) Se hai scritto "const char* const ..." sarebbe un puntatore costante a caratteri costanti. (Lo const arriva dopo la stella).

Le versioni multiple sono utili in modo che il compilatore può capire questo:

const char* my_const_var = <object_name>(); 
char* my_var = <object_name>(); 

Chris

1

Si dovrebbe fare riferimento alla "HIGH · INTEGRITÀ C++ codifica manuale STANDARD" per sapere quando si raccomanda di utilizzare la const modificatore per i membri della classe:

High Integrity CPP Regola 3.1.8: Dichiara "const" qualsiasi funzione membro della classe che non modifica lo stato visibile esternamente dell'oggetto. (QACPP 4211, 4214)

Giustificazione: Anche se la lingua fa rispettare bit a bit const correttezza, const correttezza dovrebbe essere pensato come logico, non bit a bit. Una funzione membro dovrebbe essere dichiarata const se è impossibile per un client determinare se l'oggetto è cambiato in seguito alla chiamata a tale funzione. La parola chiave 'mutabile' può essere usata per dichiarare i dati dei membri che possono essere modificati in funzioni const, questo dovrebbe essere usato solo dove i dati dei membri non influenzano lo stato visibile esternamente dell'oggetto.

class C 
{ 
public: 
    const C& foo() { return * this; } // should be declared const 
    const int& getData() { return m_i; } // should be declared const 
    int bar() const { return m_mi; }  // ok to declare const 
private: 
int m_i; 
mutable int m_mi; 
}; 

Riferimento Efficace C++ Elemento 21; Forza industriale C++ 7.13;