Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Le classi C++ sono per impostazione predefinita tipi di valore.In questo argomento vengono forniti cenni preliminari introduttivi dei tipi di valore e problemi relativi al relativo utilizzo.
Valore VS. i tipi di riferimento
Come dichiarato in precedenza, le classi C++ sono per impostazione predefinita tipi di valore.È possibile specificare quali tipi di riferimento, che consentono al comportamento polimorfico per supportare la programmazione orientata a oggetti.I tipi di valore sono talvolta visualizzati dal punto di vista del controllo del layout e di memoria, mentre i tipi di riferimento sono illustrate le classi base e le funzioni virtuali per scopi polimorfici.Per impostazione predefinita, i tipi di valore sono copiabile, che indica che è sempre disponibile un costruttore di copia o un operatore di assegnazione di copia.Per i tipi di riferimento, è possibile rendere la classe non copiabile (- disabilita il costruttore di copia e l'operatore di assegnazione di copia) e si utilizza un distruttore virtuale, che supporta il polimorfismo desiderato.I tipi di valore sono anche sui contenuti, che, quando vengono copiati, sempre forniscono due valori non modificabili separatamente.I tipi di riferimento sono sull'identità del tipo di oggetto è?Per questo motivo, "i tipi di riferimento" vengono definite anche "tipi polimorfici".
Se si desidera effettivamente un tipo di tipo di riferimento (classe di base, funzioni virtuali), è necessario disabilitare in modo esplicito la copia, come illustrato nella classe di MyRefType nel codice seguente.
// cl /EHsc /nologo /W4
class MyRefType {
private:
MyRefType & operator=(const MyRefType &);
MyRefType(const MyRefType &);
public:
MyRefType () {}
};
int main()
{
MyRefType Data1, Data2;
// ...
Data1 = Data2;
}
Compilare il codice precedente è il seguente errore:
Tipi di valore e efficienza di spostamento
Il sovraccarico di allocazione della copia viene evitato a causa delle nuove ottimizzazioni di copia.Ad esempio, quando si inserisce una stringa in corso un vettore di stringhe, non verrà sovraccarico di riallocazione di copia, solo un movimento anche se restituisce uno compilare il vettore stesso.Ciò si applica alle altre operazioni, ad esempio eseguendo un'operazione di addizione su due oggetti molto grandi.Come attivare le ottimizzazioni delle operazioni di valore?In alcuni compilatori C++, il compilatore non questo automaticamente in modo implicito, come i costruttori di copia può essere generato automaticamente dal compilatore.Tuttavia, in Visual C++, la classe dovrà scegliere- "in" spostare l'assegnazione e costruttori dichiarandolo nella definizione della classe.Questa operazione viene eseguita tramite il doppio riferimento rvalue di e commerciali (&&) nelle dichiarazioni di funzione membro appropriate e la definizione di metodi del costruttore di spostamento e di assegnazione di spostamento.È inoltre necessario inserire codice corretto "rubate le budella" dall'oggetto di origine.
Come stabilire se è necessario un movimento attivato?Se già si è necessaria la costruzione abilitata, si copia probabilmente si desidera che il movimento attivato se può essere più conveniente di una copia completa.Tuttavia, se si è necessario il supporto di spostamento, non significa necessariamente che si copia abilitata.In questo caso sarà sarebbe denominato "un tipo di spostamento".Un esempio è già nella libreria standard è unique_ptr.Nota come rapida, auto_ptr precedente è deprecato ed è stato sostituito da unique_ptr con precisione a causa della mancanza di supporto della semantica di spostamento nella versione precedente di C++.
Mediante la semantica di spostamento è possibile ritorno-da- valore o inserzione-in- centrale.Lo spostamento è un'ottimizzazione di copia.Vi è alcuna necessità di allocazione heap come soluzione alternativa.Si consideri il seguente pseudocodice:
#include <set>
#include <vector>
#include <string>
using namespace std;
//...
set<widget> LoadHugeData() {
set<widget> ret;
// ... load data from disk and populate ret
return ret;
}
//...
widgets = LoadHugeData(); // efficient, no deep copy
vector<string> v = IfIHadAMillionStrings();
v.insert( begin(v)+v.size()/2, "scott" ); // efficient, no deep copy-shuffle
v.insert( begin(v)+v.size()/2, "Andrei" ); // (just 1M ptr/len assignments)
//...
HugeMatrix operator+(const HugeMatrix& , const HugeMatrix& );
HugeMatrix operator+(const HugeMatrix& , HugeMatrix&&);
HugeMatrix operator+( HugeMatrix&&, const HugeMatrix& );
HugeMatrix operator+( HugeMatrix&&, HugeMatrix&&);
//...
hm5 = hm1+hm2+hm3+hm4+hm5; // efficient, no extra copies
Attivare lo spostamento dei tipi di valore appropriati
Per una classe tipo di valore in cui l'operazione può essere più conveniente di una copia completa, abilitare la costruzione di spostamento e assegnazione di spostamento per maggiore efficienza.Si consideri il seguente pseudocodice:
#include <memory>
#include <stdexcept>
using namespace std;
// ...
class my_class {
unique_ptr<BigHugeData> data;
public:
my_class( my_class&& other ) // move construction
: data( move( other.data ) ) { }
my_class& operator=( my_class&& other ) // move assignment
{ data = move( other.data ); return *this; }
// ...
void method() { // check (if appropriate)
if( !data )
throw std::runtime_error("RUNTIME ERROR: Insufficient resources!");
}
};
Se si abilita la costruzione o assegnazione di copia, anche abilitare la costruzione o assegnazione di spostamento se può essere più economica di una copia completa.
Alcuni tipi di valore non sono solo spostamento, ad esempio quando non è possibile usare una risorsa, solo proprietà di trasferimento.Esempio: unique_ptr.
Sezione
Contenuto
Vedere anche
Concetti
Sistema di tipi C++ (C++ moderno)