Typy hodnot (moderní C++)
Výchozí hodnota typy jsou třídy jazyka C++.Toto téma obsahuje přehled úvodní typy hodnot a otázky týkající se jejich použití.
Hodnota VS. referenční typy
Výše uvedeno, třídy jazyka C++ jsou výchozí hodnoty typu.Může být zadána jako odkazové typy, které umožňují polymorfní chování pro podporu objektově orientované programování.Hodnotové typy jsou někdy zobrazit z hlediska paměti a rozložení ovládacího prvku, že odkazové typy jsou o základní třídy a virtuální funkce pro účely polymorfní.Ve výchozím nastavení jsou typy hodnot kopírovatelná, což znamená, že vždy existuje konstruktor kopie a operátor přiřazení kopie.Pro odkazové typy, vytvoříte třídu bez kopírovatelná (zakázat kopie konstruktoru a operátor přiřazení kopie) a použít virtuální destruktor, které podporuje jejich zamýšlené polymorfismus.Hodnotové typy jsou také o obsahu, které při kopírování, vždy vám dvou nezávislých hodnot, které lze upravit samostatně.Odkazové typy jsou o identitě – jaký druh objektu se jedná?Z tohoto důvodu "referenční typy" jsou také označovány jako "polymorfní typy".
Pokud Opravdu chcete odkaz jako typ (základní třídy, virtuální funkce), budete muset explicitně zakázat kopírování, jak je znázorněno MyRefType třídy v následujícím kódu.
// cl /EHsc /nologo /W4
class MyRefType {
private:
MyRefType & operator=(const MyRefType &);
MyRefType(const MyRefType &);
public:
MyRefType () {}
};
int main()
{
MyRefType Data1, Data2;
// ...
Data1 = Data2;
}
Kompilace kódu výše má za následek následující chybová zpráva:
Hodnota typů a přesunout účinnosti
Režie přidělení kopie se lze vyhnout, z důvodu optimalizace novou kopii.Například při vložení řetězce uprostřed vektor řetězce bude žádné kopie definitivně režie, pouze cestách - i v případě, že to má za následek růst vektoru, sám.To platí také pro jiné operace, například provedením operace na dvou objektech velmi velké.Jak povolit optimalizace provozu tyto hodnoty?V některé kompilátory jazyka C++ kompilátor umožní to pro vás implicitně, podobně jako kopie konstruktory mohou automaticky generovanými kompilátorem.Však v aplikaci Visual C++, vaše třída bude nutné "opt-in" na přiřazení a konstruktory přesunout tak, že jej deklarujete v definici vaší třídy.To lze provést pomocí Dvojitý ampersand (& &) rvalue odkaz v příslušné členské funkce deklarace a definice konstruktoru přesunout a přiřazení metody přesunu.Také je třeba vložit správný kód pro "ukrást střev" ze zdrojového objektu.
Jak se rozhodnout, je nutné přesunout povolena?Pokud již víte, že je třeba zkopírovat stavební povolení, pravděpodobně chcete přesunout povolena v případě, že může být levnější než hluboká kopie.Však pokud víte, že je třeba přesunout podporu, to neznamená nutně má povoleno kopírovat.Takovém případě by nazývá "pouze pro přesunutí typu".Jako příklad již ve standardní knihovně unique_ptr.Jako poznámku na okraj, původní auto_ptr je zastaralý a byl nahrazen unique_ptr přesně nedostatečnou podporu sémantiky přesunutí v předchozí verzi jazyka C++.
Pomocí přesunutí sémantiky můžete vrátit hodnoty nebo vložit do středu.Přesun je optimalizace výtisku.Je třeba pro přidělení haldy jako dočasné řešení.Zvažte následující pseudokódu:
#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
Umožňuje přesunout odpovídající hodnoty typů
Pro hodnoty podobné třídy, kde může být levnější než hlubokou kopii přesunout povolit přesun konstrukce a přesunout přiřazení pro zvýšení efektivity.Zvažte následující pseudokódu:
#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!");
}
};
Je-li kopie stavby nebo přiřazení, také povolte přesunutí stavby nebo přiřazení Pokud může být levnější než hluboká kopie.
Některé bez hodnoty jsou typy přesunout jen, například pokud nelze klonovat prostředek pouze převést vlastnictví.Example: unique_ptr.
Oddíl
Obsah
Viz také
Koncepty
Systém typů C++ (Příručka programování moderních C++)