Professional Documents
Culture Documents
Sažetak 1. Uvod
Programski jezik C++ neprestano se razvija te 1. Introduction
je do sada objavljeno nekoliko C++ standarda.
Međutim, zadnjim C++ 11 standardom ovaj Kada je riječ o pisanju visoko optimiziranog
programski jezik dobio je mnogo novih programskog koda gdje nam je bitna brzina
mogućnosti. Ispravljeni su određeni nedostatci izvođenja, programski jezik C++ je jedno od
samog programskog jezika te su dodane mnoge najboljih rješenja . Iako su u praksi najčešće
nove značajke koje olakšavaju način na koji se sporiji, programski jezici novijih generacija
piše i dodatno optimizira programski kod. su također imali određene značajke kojima su
Popis svih značajki koje dolaze s C++ 11 se isticali u usporedbi s C++om. Jedna od tih
standardom poprilično je velik. Stoga su u ovom značajki je, primjerice, sakupljač smeća (eng.
radu opisane neke od najvažnijih poput semantike garbage collector) koji je automatski uništavao
prijenosa i pametnih pokazivača. Upotrebom dinamički alocirane objekte nakon što isti nisu
ovih novih značajki C++ programi postaju još više bili u upotrebi (dosegu). Tu su također i
brži i sigurniji za pisanje pa je zato i njihovo lambda izrazi (anonimne funkcije), delegati itd.
razumijevanje od ključne važnosti. Stoga, unatoč svojoj brzini C++ je na neki način
trebao ostati u koraku s najnovijim tehnikama
Ključne riječi: programiranje, c++, c++11,
programiranja koje se koriste u novijim objektno
standard, pokazivači, semantika prijenosa.
orijentiranim programskim jezicima.
Abstract Još 1998. g. pojavljuje se prvi C++ standard
(ISO/IEC 14882:1998) popularno zvan C++98.
C++ programming language is continuously being
Programskom jeziku C++ ovim su standardom
developed. Up to this date several C++ standards
dodane prve ozbiljnije značajke i mogućnosti.
have been released. However, C++ 11 Standard
Tako je primjerice sada bilo moguće koristiti
has provided this programming language with
dynamic_cast pretvorbu, typeid operator,
many new possibilities. Certain disadvantages of
kontejnere, algoritme, iteratore, funkcijske
the programming language have been corrected.
objekte itd. Također, jedna od važnijih značajki
Also, many new properties have been added,
koju je uveo C++ 98 bila je prva implementacija
which makes it easier to write and additionally
pametnog pokazivača (auto_ptr) koji će
optimise the programming code. The list of new
naknadno daljnjim revizijama standarda biti
properties which come with C++ 11 Standard is
zamijenjen pametnim pokazivačima unique_ptr
quite long. Therefore, this paper will describe
i shared_ptr.
some of the most important properties such as
C++ standard kasnije je doživio još nekoliko
move sematics and smart pointers. Using these
manjih revizija. Prva od njih je bila 2003. godine
new features C++ applications are becoming
pod nazivom C++03, a njome se ispravilo
faster and safer for writing. Hence, their
mnoštvo prijavljenih problema s prethodno
understandind is of key value.
objavljenim C++98 standardom. Kasnije 2005.
Keywords: programming, c++, c++11, standard, C++ komisija za razvoj objavila je prvi tehnički
pointers, move semantics izvještaj (TR1) detaljno opisujući razne nove
32 287
POLYTECHNIC & DESIGN Vol. 3, No. 1, 2015.
planirane značajke. Novi standard neformalno postojati nakon evaluacije izraza. Zapravo,
je nazvan C++0X te je konačno objavljen tek rvalue vrijednosti privremeni su objekti koji se
sredinom 2011. g. Nakon toga je preimenovan u upotrebom C++11 standarda mogu detektirati te
C++11. [1] dodatno iskoristiti prilikom upotrebe semantike
Tek od tada službeno C++ podržava prijenosa.
mnoštvo novih tehnika i pristupa koji se mogu Kako C++11 standardom možemo detektirati
primjenjivati pri pisanju C++ aplikacija. Jedna je li funkciji predana lvalue ili rvalue
od najvažnijih je semantika prijenosa kojom se vrijednost tako možemo izvršiti i dodatne
omogućuje dodatna optimizacija pri razvijanju optimizacije programskog koda. Primjerice,
aplikacija. Naime, sada C++ aplikacija može class MojeIntPolje{
prepoznati da li se radi s privremenim ili stalnim public:
objektima i na osnovu toga dodatno ubrzati
int* p;
izvršavanje aplikacija. [2]
int size;
Na području sigurnosti su također mnogi
MojeIntPolje(int n) :
noviteti, a najvažniji od njih su pametni pokazivači.
size(n){
Pomoću njih C++ programeri više ne moraju ručno
dealocirati zauzetu memoriju već se ona automatski p = new int[n];
briše nakon što više nije potrebna. [3] }
// Kopirni konstruktor
2. Prednosti semantike prijenosa (duboko kopiranje)
u C++ aplikacijama MojeIntPolje(const
MojeIntPolje& X){
2. Advantages of move semantics
p = new int[X.
in C++ applications
size];
Programski jezik C++ oduvijek je glasio for(int i = 0; i <
kao jedan od najbržih, omogućavajući X.size; i++)
programerima pisanje programskog koda s p[i] =
visokim stupnjem optimizacije. Objavom X.p[i];
C++11 standarda ovaj programski jezik postao size = X.size;
je čak još brži i optimiziraniji. Najveći razlog }
tome je upravo korištenje semantike prijenosa ~MojeIntPolje(){
(eng. move semantics) kojom se eliminiraju
nepotrebna kopiranja objekata tamo gdje je delete[] p;
to moguće, a time i smanjuje opterećenje }
procesora pri radu aplikacije.
};
Za potpuno razumijevanje semantike prijenosa
potrebno je razlikovati dva tipa vrijednosti, tj. Ova klasa predstavlja polje podataka tipa int.
lvalue i rvalue. Prvi tip predstavlja izraz koji U sebi sadrži pokazivač na niz koje se alocira
se nalazi s lijeve strane operatora pridruživanja te unutar konstruktora te uništava u destruktoru
ga je moguće adresirati. Zato je lvalue najčešće klase. Deklarirajmo sljedeće objekte ove klase:
nekakav objekt ili funkcija. MojeIntPolje polje1(10); //
int x = 3 + 4; Konstruktor!
U ovoj deklaraciji x je lvalue vrijednost MojeIntPolje polje2 = polje1; //
jer je riječ o objektu koji postoji i nakon
Kopirni konstruktor!
evaluacije izraza s desne strane te ga je moguće
adresirati. S druge strane 3 + 4 predstavlja MojeIntPolje
rvalue vrijednost i to samo zato jer je riječ polje3(MojeIntPolje(10)); //
o privremenoj vrijednosti koja više neće konstruktor (i kopirni konstruktor?)
33
POLYTECHNIC & DESIGN Vol. 3, No. 1, 2015.
U prve dvije linije koda jasno je što se U prvom slučaju polje2 objekt poprima
događa, a problematična je tek zadnja linija vrijednost objekta polje1. Međutim, polje1
čiji rezultat ovisi o prevoditelju. Ono što bismo je lvalue vrijednost jer ju je moguće adresirati
očekivali jest da se zbog privremenog objekta te će postojati i dalje nakon izvršenja tog izraza.
MojeIntPolje(10) prvo pokrene konstruktor Zbog toga je nužno da se izvrši kopirni konstruktor
s parametrima, a nakon toga kopirni konstruktor s dubokim kopiranjem. S druge strane, u drugoj
koji bi svojstva tog privremenog objekta kopirao naredbi objektu polje3 dodjeljujemo rvalue
u objekt polje3. Ipak, ukoliko vaš prevoditelj vrijednost tj. privremeni objekt.
koristi RVO (eng. Return Value Optimization) Problem s drugom naredbom jest da je
onda bi se zadnja linija koda interpretirala privremeni objekt MojeIntPolje(10) već
kao MojeIntPolje polje3(10). Ovime dinamički alocirao niz od 10 elemenata te će
prevoditelj izbjegava kopirni konstruktor i izravno ga uništiti odmah nakon izvršenja kopirnog
stvara objekt na osnovu parametara koji su konstruktora objekta polje3. Pitanje je onda
proslijeđeni privremenom objektu. zašto uopće raditi kopiju privremenog objekta i
RVO optimizacija nije karakteristika svih time gubiti procesorsko vrijeme ako već postojeći
prevoditelja i zato s takvim kodom treba biti na niz privremenog objekta njemu ionako više
oprezu kako aplikacija ne bi izgubila puno na neće trebati? Stoga, umjesto da radimo kopiju
performansama tokom izvođenja. privremenog objekta možemo prenijeti njegova
postojeća svojstva (dinamički alocirani niz) u novi
objekt. Upravo to je semantika prijenosa.
Prilikom realizacije semantike prijenosa
koriste se prijenosni konstruktor (eng. move
constructor) i operator pridruživanja sa
semantikom prijenosa. Kao parametre im
predajemo rvalue reference, a one umjesto
jednog znaka ‘&’ sadrže dva znaka ‘&&’.
Primjerice,
// Konstruktor prijenosa s rvalue
referencom
Slika 1 Semantika kopiranja
Figure 1 Copy semantics MojeIntPolje(MojeIntPolje&&
Kao što je vidljivo iz slike korištenjem privremeni){
semantike kopiranja (kopirni konstruktor) oba p = privremeni.p; // Preusmjeri
objekta dobila su nove memorijske lokacije za
pokazivač
svoje pokazivače, a nakon toga još je potrebno
izvršiti kopiranje podataka iz jednog dinamički privremeni.p = NULL; //
alociranog niza u drugi. Sve ovo nužno je privremeni objekt više nije vlasnik
potrebno ukoliko je riječ o kopiranju iz jednog pokazivača
već postojećeg objekta (lvalue vrijednosti) u
size = privremeni.size;
drugi objekt. Ono što se dodatno optimiziralo
kroz C++11 kopiranje je rvalue vrijednosti, tj. }
privremenog objekta u novi objekt. U tu svrhu
Ovako bi izgledao prijenosni konstruktor
sada se može koristi semantika prijenosa.
za gore opisanu klasu. Kao parametar prima
U prethodnom primjeru demonstrirali smo oba
rvalue referencu i umjesto rezerviranja
poziva:
nove memorijske lokacije i kopiranja (kopirni
MojeIntPolje polje2 = polje1; konstruktor) jednostavno preuzima pokazivač iz
MojeIntPolje privremenog objekta.
Što se točno događa u kodu vidljivo je iz slike.
polje3(MojeIntPolje(10));
Objekt polje3 pomoću prijenosnog konstruktora
34
POLYTECHNIC & DESIGN Vol. 3, No. 1, 2015.
35
POLYTECHNIC & DESIGN Vol. 3, No. 1, 2015.
36
POLYTECHNIC & DESIGN Vol. 3, No. 1, 2015.
37
POLYTECHNIC & DESIGN Vol. 3, No. 1, 2015.
38
POLYTECHNIC & DESIGN Vol. 3, No. 1, 2015.
}
Tablica 2 Rezultati testiranja pri kreiranju shared_ptr
objekata };
Table 2 Testing results upon creating shared_ptr objects
Za demonstraciju cirkularne ovisnosti kreirat
ćemo 3 osobe pomoću shared_ptr pametnih
Broj shared_ptr make_shared pokazivača.
objekata (ms) (ms) shared_ptr<Osoba> Ante(make_
100.000 46 31 shared<Osoba>(“Ante”));
1.000.000 422 390 shared_ptr<Osoba> Ivica(make_
2.000.000 843 702 shared<Osoba>(“Ivica”));
5.000.000 2012 1701
10.000.000 4068 3432 shared_ptr<Osoba> Ivan(make_
20.000.000 7921 6443 shared<Osoba>(“Ivan”));
39
POLYTECHNIC & DESIGN Vol. 3, No. 1, 2015.
40
POLYTECHNIC & DESIGN Vol. 3, No. 1, 2015.
5. Reference
5. References
[1] A. S., »History of C++,« [Mrežno]. Avail- [3] H. Sutter, »Smart Pointers,« 29 5 2013.
able: http://www.cplusplus.com/info/his- [Mrežno]. Available: http://herbsutter.
tory/. [Pokušaj pristupa 13 7 2014]. com/2013/05/29/gotw-89-solution-smart-
[2] A. Allain, »Move semantics and rvalue pointers/. [Pokušaj pristupa 16 7 2014].
references in C++11,« [Mrežno]. Available: [4] D. Kieras, »Using C++11’s Smart Point-
http://www.cprogramming.com/c++11/ ers,« Michigan, 2013.
rvalue-references-and-move-semantics-in-
c++11.html. [Pokušaj pristupa 14 7 2014].
AUTORI · AUTHORS
Željko Kovačević, struč. spec. ing. techn. inf Miroslav Slamić is currently
- nepromjenjena biografija nalazi se u časopisu professor-lecturer at Polytechnic
Polytechnic & Design Vol. 2, No. 1, 2014. of Zagreb. Courses that he
teaches are related to algorithms
Korespondencija: and data structure, and
zeljko.kovacevic@tvz.hr programming languages and
paradigms. He obtained his
PhD in Aviation, Rocket and Space technology
Science from Faculty of Electrical Engineering
and Computing Zagreb. His academic research
interest include interactive real-time simulations,
virtual reality and applications in staff training,
diagnostics and therapy. He also worked on
management of massive multimedia contents.
Special scientific interest and research projects
he had in missile guidance systems and theory
of differential games. He has more than 25
professional, academic and scientific papers
published in these areas.
41