Nacrt C++0x od marta 2010.
C++0x (u izgovoru: si plas plas ou eks[1]) je nezvanični naziv novog standarda programskog jezika C++, koji je još uvek u razvojnoj fazi. Namena mu je da zameni postojeći standard za C++, ISO/IEC 14882, koji je objavljen 1998. i ažuriran 2003. Ove prethodnice su neformalno poznate kao C++98 i C++03. Novi standard obuhvata nekoliko dodataka u jezgru jezika i proširuje standardnu biblioteku, obuhvatajući veći deo biblioteka C++ Technical Report 1 (TR1). Najverovatnije će biblioteka specijalnih matematičkih funkcija biti izuzetak. Pošto standard još uvek nije završen, ovaj članak možda ne oslikava ažurno stanje C++0x, već nacrt ovog međunarodnog standarda, N3092, koji je objavljen u martu 2010.
Očekuje se da će kompletiranje i objavljivanje standarda sačekati kraj 2011. godine.
Poboljšanja performansi tokom izvršavanja programa[uredi | uredi izvor]
Naredne karakteristike jezika su prvenstveno napravljene da pruže mogućnost za poboljšanje rada nekog programa. Ovo se može ticati uštede memorije i procesorskog vremena.
Rvalue reference i razmena memorije među objektima[uredi | uredi izvor]
Rvalue reference omogućavaju efikasno premeštanje sadržaja kompleksnih struktura iz jedne u drugu. Npr. u standardnom C++-u je moguće da jedna funkcija (f2) oformi niz tipa std::vector<T> i vrati ga funkciji koja ju je pozvala (f1). U tom slučaju će niz napravljen u f2 prvo biti potpuno iskopiran u odgovarajući niz iz f1, a potom uništen. Kopiranje i uništavanje niza iz f2 je suvišan posao, jer ako niz već postoji u memoriji tokom f2, nema potrebe niti praviti njegovu kopiju, niti njega brisati. Treba ga samo na neki način nazad proslediti.
U dosadašnjem C++-u je bilo moguće da f1 napravi svoj niz, i dostavi ga f2 na popunjavanje. Od C++0x je takođe moguće da se niz nastao u f2 vrati u f1 kao Rvalue referenca. U tom slučaju će povratni tip od f2 biti std::vector<T>&&. Da bi ovako vraćena Rvalue referenca bila uspešno prihvaćena od objekta tipa std::vector<T> iz f1, taj tip mora imati definisan tzv. konstruktor premeštanja (engl. move constructor), koji preuzima sve iz objekta na koga je dobio Rvalue referencu, i ostavlja ga praznim. Ukoliko ovakav konstruktor nije napisan, biva korišćen stari pristup kopiranja i brisanja.
Iz bezbednosnih razloga jezik ne dozvoljava jednostavno ostavljanje rvalue referenci na objekte kojima je dodeljeno ime. Da bi se dobila rvalue referenca na ovakav objekat, treba koristiti šablon funkcije std::move<T>().
Generalizovane konstantne vrednosti[uredi | uredi izvor]
U standardnom C++ nije moguće da se funkcije, koje vraćaju konstantnu vrednost, koriste u izrazima koji moraju biti nedvosmisleno konstantni još tokom kompajliranja. Ovakav izraz je npr. dužina statički definisanog niza ili sadržaj enumeracija. Na primer:
const int DajPet() {return 5;}
int niz[DajPet() + 7]; // Требало би да направи статички низ са
// 12 елемената. Не ради у C++.
Ovo nije moguće u C++-u, jer se vrednost koju funkcija DajPet() vraća ne tretira kao konstanta, iako ona to u stvari jeste. C++0x ima novu ključnu reč, constexpr, kojom programer može da naznači da neka funkcija vraća konstantnu vrednost:
constexpr int DajPet() {return 5;}
Nakon ove naznake, moguće je funkciju koristiti kao bilo koju brojevnu konstantu. Prednost ovakvog pristupa je u tome što ovakvim definisanjem funkcije njena vrednost biva određivana i upotrebljavana tokom kompajliranja programa, a ne tokom njegovog izvršavanja, što znači uštedu procesorskog vremena.
Alternativa ovome u C++-u su konstantni izrazi, definisani npr. sa:
#define DajPet 5
ili
const int DajPet = 5;
Redefinisanje POD-tipova[uredi | uredi izvor]
U standardnom C++-u, struktura (struct) mora da ispuni brojna pravila da bi bila smatrana za POD-tip (engl. plain old data). Dobar razlog za postojanje što više ovakvih tipova je kompatibilnost sa C-om. Pošto je spisak pravila definisan u C++03 bio previše restriktivan, u C++0x se ova pravila opuštaju.
Svaki tip definisan kao klasa (class) ili struktura se smatra POD-tipom ako je trivijalna, napisana prema standardnom obrascu (engl. standard layout) i ako su sve njene enkapsulirane članice trivijalne.
Klasa ili struktura je trivijalna, ako:
- Ima trivijalan podrazumevani konstruktor (engl. default constructor).
- Ima trivijalan kopi-konstruktor (engl. copy constructor).
- Ima trivijalan operator dodele (engl. assignment operator).
- Ima trivijalan destruktor (engl. destructor), koji nije virtuelan.
Klasa ili struktura je napisana prema standardnom obrascu, ako:
- Sadrži samo nestatičke, elemente, koji su takođe napisani prema standardnom obrascu.
- Ima ista prava pristupa (public, private, protected) svim nestatičkim članicama.
- Nema virtuelnih funkcija.
- Nema virtuelnih baznih klasa.
- Sve bazne klase su joj takođe napisane prema standardnom obrascu
- Nema baznih klasa istog tipa, definisane kao prve ne-statične članice.
- U celoj hijerarhiji se može naći samo jedna klasa sa nestatičnim članicama. Važi ili-ili:
- Nema baznih klasa sa nestatičnim članicama
- Nema nestatičnih podataka u krajnje izvedenim klasama i ima najviše jednu baznu klasu sa nestatičnim članicama.
Poboljšanja vremena kompajliranja[uredi | uredi izvor]
U standardnom C++-u implementacija šablona biva instancirana u svakoj jedinici programa u kojoj se koriste, što povećava vreme kompajliranja. C++0x omogućava da se implementacije šablona označe kao eksterne (rečju extern), što označava da tu implementacija ne treba instancirati u toj jedinici, već je potražiti u drugoj i koristiti tamošnju instancu. Dakle, sadašnje instance šablona:
template class std::vector<T>;
Bi sa ovim izgledale ovako:
extern template class std::vector<T>;
Poboljšanja upotrebljivosti jezika[uredi | uredi izvor]
Ova poboljšanja su prvenstveno napravljena da bi olakšala upotrebu jezika tj. unapređuju sigurnost rukovanja tipovima, umanjuju ponavljanje koda, otežavaju javljanje grešaka itd.
Spiskovi argumenata[uredi | uredi izvor]
Standardni C++ od C-a pozajmljuje koncept spiskova argumenata promenljive dužine (engl. variable argument list, va_list). Implementacija ovog je zahtevala mnogo više koda nego npr. u Javi, i nije bila primenjiva na tipove koji nisu odgovarali C++03 definiciji POD-tipova.
C++0x uvodi novi koncept, kod koga se ovi spiskovi argumenata vezuju za šablon std::initializer_list.
Npr, umesto dosadašnje deklaracije funkcije sa:
void UzmiNiz(int n, ...);
I izvlačenja pristiglih argumenata pomoću va_list, va_arg i va_end, C++0x koristi:
void UzmiNiz(std::initializer_list<float> spisak);
Pri čemu promenljiva spisak sadrži podake o broju promenljivih, a poziv funkcije izgleda ovako:
UzmiNiz({1.2f, -3.45f, 5.2f});
Reference[uredi | uredi izvor]
- ^ Bjarne Strostrup o C++0x Arhivirano na sajtu Wayback Machine (17. oktobar 2011) — video na guglu, 3:26