C++

објектно-оријентисан програмски језик
(преусмерено са Це Плус Плус)

C++ је виши програмски језик који је првобитно развијен у Беловим лабораторијама (лабораторији телекомуникационе компаније Bell) за објектно оријентисано програмирање у пројекту под руководством Бјарнеа Строуструпа током 1980-их као проширење програмског језика C, па му је оригинално име било „C са класама“ (енгл. C with classes). Због велике потражње за објектно оријентисаним језицима и способностима, стандард за програмски језик C++ ратификован је 1998. у стандарду ISO/IEC 14882.

C++
Званични лого
Изговара сеЦе++
Моделвишепарадигмални: процедурални, императивни, функционални, објектно-оријентисани, генерички, модуларни
Појавио се1985.; пре 39 година (1985)
Аутор(и)Бјарне Стравструп
Дизајнер(и)ISO/IEC JTC 1 (Joint Technical Committee 1) / SC 22 (Subcommittee 22)]] / WG 21 (Working Group 21)
Актуелна верзијаC++20 (ISO/IEC 14882:2020)
Датум актуелне верзије15. децембар 2020.; пре 3 године (2020-12-15)
Оперативни системивишеплатформски
Веб-сајтisocpp.org

Историја C++-а

уреди

Почетком осамдесетих година у Беловим лабораторијама Бјарне Строуструп, дански научник, радећи на проширивању језика C развио је суштински нов језик кога је назвао C са класама.[1][2]Закључио је да је Simula имала веома добре функције за развој великих програма, али је тај језик био преспор за коришћење у пракси. BCPL (енгл. Basic Combined Programming Language) је био брз али превише ниског нивоа за развој великих програма. Строуструп је изабрао C као базу, јер је C био генерално оријентисан, брз и у широкој употреби. Почео је да ради на побољшању програмског језика C додајући му функције сличне онима које има Simula. Такође, утицај су имали ALGOL 68, Ada, CLU и ML. Аутор је желео да побољша језик C развојем подршке објектно-оријентисаном програмирању. У 1983. години тај назив је промењен у C++.

Строуструпов C са класама је на почетку додао C компајлеру могућности као што су класе, наслеђивање, јако типизирање, редне функције и подразумеване вредности аргумената.[3] Строуструп је 1982. почео да развија наследника C са класама, који је назвао "C++" (++ је унарни оператор инкрементирања у језику C), након што је разматрао неколико других имена. Додате су нове могућности, међу којима су виртуелне функције, име функције и преклапање оператора, референце, константе, заузимање меморије (new/delete), побољшану проверу типова, и коментаре у једном реду у стилу језика BCPL са две косе црте (//). Даље, Строуструп је развио Cfront, нови самостални компајлер за C++.

Језик C++ се разликује од обичног C-а пре свега подршком објектно-оријентисаном програмирању. Међутим, у њему има и низ нових могућности, које нису објектног карактера, због којих је писање програма који нису објектне природе удобније реализовати у C++-у него у C-у.

C++ је данас неспорно један од најмоћнијих, али и најкомплекснији програмски језик. Због компактности програма, брзине извршавања и преносивости представља незаменљив алат сваког професионалца. Због ових особина заузима једно од доминантних места у свету професионалног програмирања.

Назив

уреди

Према Строуструпу назив C++ симболизује еволуционарни напредак од C-a.[4] Назив је осмислио Рик Масцити. Када је Масцити био неформално интервјуисан о настанку имена 1992. године, одговорио је да је назив настао у духу програмирања, јер оператор за инкрементацију (++) симболише напредак. Тада је било уобичајена пракса да се тако означава побољшана верзија софтвера.

Развојна окружења

уреди

Интегрисано развојно окружење обједињава све кораке односно фазе развоја софтвера у јединствену целину што олакшава писање и тестирање програма.

Неки од најпознатијих интегрисаних развојних окружења, чије се коришћење истовремено препоручује у оквиру предмета C/C++ програмски језик, су:

  • Microsoft‘s Visual C++ (Windows)
  • Code::Blocks (Windows, Linux)
  • Netbeans C/C++ (Windows, Linux)

Синтакса језика C++

уреди

C++ има додатне резервисане речи у односу на C, а такође има и дефинисан логички тип податка bool који у C-у не постоји. У језику C++ као додатак имамо следеће најчешће коришћене службене речи:


asm        bool        catch        char 
class      delete      explicit     export 
false      friend      inline       mutable
namespace  new         operator     private 
protected  public      template     this 
throw      true        try          typename
using      virtual

Логички тип bool

уреди

У C++-у за величине логичког типа могу се уместо 0 и 1 користити вредности true (тачно) и false (нетачно). Логичка константа false је једнака нули, а свака друга вредност се третира као тачна. Када се true конвертује у цео број резултат је 1. За опис променљивих логичког типа користи се резервисана реч bool.

Пример C++ програма

уреди

Анализирајмо следећи пример у програмском језику C++.

// This program outputs the message "Hello, World!" to the monitor

#include <iostream>
using std::cout; using std::endl;

 int main()
 {
     cout << "Hello world!" << endl; 
     return 0;
 }

Линија 1 представља коментар. Коментари су написани у корист програмера који анализирају код, и обично се користе за сумирање, идентификацију сврхе или појашњење сегмената кода.

Линија 3 је предпроцесорска наредба или директива којом дајемо инструкције компајлеру да желимо да користимо iostream библиотеку. Библиотека iostreamсадржи скуп унапред дефинисаних операција које можемо да укључимо (#include) у наш програм.

Линија 4 је декларација (using declaration). У оквиру библиотеке iostream, постоји тачно одређени сегмент (именски простор std) где су смештене дефиниције операција cout и endl. Зато је неопходно коришћењем using декларације указати компајлеру да унутар одељка под називом std (скраћеница за стандард) пронађе дефиниције за cout и endl које користимо у линији 8.

У линији 6 декларишемо main() функцију.

Линије 7 и 10 указују компајлеру који део програмског кода припада main() функцији. Све линије кода које се налазе између отворене витичасте заграде у линији 7, и затворене витичасте заграде у линији 10 представљају део main() функције.

У линији 8 се налази cout, специјални објекат за обављање излазних операција у секвенцијалним медијима као што су екран, датотека итд. Симбол << је оператор излаза (output operator или insertion operator), који указује компајлеру да све што следи након симбола треба бити одштампано на екрану/конзоли. endl је специјалан симбол који курсор пребацује у следећи ред конзоле.

Линија 9 је повратна наредба (return statement). Након егзекуције програма шаље се повратна вредност систему која указује да ли је програм извршен успешно или не. У овом конкретном примеру, наредбом return оперативном систему се враћа вредност нула 0 што значи да је програм извршен без грешака. Модерни компајлери аутоматски праве повратну наредбу. То значи да чак и ако немамо повратну наредбу унутар наше главне функције main(), и даље ћемо на екрану имати информацију да ли је програм извршен успешно или не.

Референце у језику C++

уреди

Референцна променљива је псеудоним, алиас, што у ствари представља други назив за постојећу променљиву. Након што је референца једном иницијализована, могуће је приступити променљивој или преко њеног назива или коришћењем референце.

Поређење показивача и референци

уреди

Референце се често мешају са показивачима, међутим постоје три главне разлике између показивача и референци, а то су:

  • У програму не може да постоји null референца. Увек мора да важи претпоставка да је референца повезана са легитимним тј. активним делом меморије односно складишта (storage).
  • Једном иницијализована референца не може бити промењена да референцира другу променљиву или објекат. Супротно референцама, показивачи могу да буду промењени и да у различитим временским тренуцима показују на различите променљиве односно објекте.
  • Референца мора бити иницијализована приликом креирања, за разлику од показивача који могу бити иницијализовани у било ком тренутку.

Креирање референци у C++-у

уреди

О имену променљиве можемо размишљати као о лабели која је се односи на локацију променљиве у меморији. Ако кренемо корак даље, о референцама можемо размишљати као о другој лабели која се односи на ту меморијску локацију. Стога је могуће приступити садржају променљиве или преко назива променљиве или преко референце. Претпоставимо да имамо следеће променљиве у програму:

int i = 17;
double d;

Можемо затим, на основу дефинисаног правила, декларисати референцу за променљиву на следећи начин:

int& r = i;
double& s = d;

Ознака & (амперсенд) се у C++-у чита као референца. Стога, прву декларацију можемо прочитати као "r је целобројна референца променљиве i" а другу као "s је реална double референца променљиве d".

Примена референци

уреди

Референце се користе када подаци похрањени у параметрима функције треба да буду видљиви и изван те функције (нпр. у главној функцији). Нпр. функција da_li_je_paran сабира елементе који припадају низу niz[] и испитује да ли је збир (zbir ) паран. Параметри &zbir i &rezultat су означени као референце, стога су подаци који они садрже видљиви изван функције da_li_je_paran (у главној функцији).

#include <iostream>

void da_li_je_paran(int niz[], int &zbir, int size, bool &rezultat)
{
    for (size_t i{}; i < size; ++i)
    {
        zbir+= niz[i];

        if (zbir% 2 == 0)
        {
            rezultat= true;
        }
    }
}

int main()
{
    bool rezultat;
    int zbir{};
    int niz[]{3, 6, 7, 8, 4, 8, 3, 2, 6, 7};
    da_li_je_paran(niz, zbir, std::size(niz), rezultat);
    std::cout << zbir << '\n';
    std::cout << std::boolalpha << rezultat << '\n';
    return 0;
}

C++ и објектно-оријентисано програмирање

уреди

C++ потпуно подржава објектно-оријентисано програмирање, укључујући четири основна концепта објектно-оријентисаног програмирања: енкапсулацију, апстракцију, наслеђивање и полиморфизам.

Класе

уреди

Основна сврха C++ програмирања је да се дода објектна оријентација C програмском језику. Класе (енгл. class) су централна одлика C++-а која управо подржава објектно оријентисано програмирање. Њих у контексту објектног језика C++ треба схватити као специфичан, кориснички дефинисан тип података који се користи да опише реално постојеће објекте. Класе обухватају атрибуте али и акције које служе да симулирају те реално постојеће објекте. По синтакси се декларација класе може најближе повезати са начином декларисања структура података. У складу са принципима ООП класе за разлику од структура, осим података садрже и функције чланице (енгл. member functions). Подаци и методе унутар класе се називају чланице класе. Класе се користе са циљем да се специфицира форма објеката. Објекти (енгл. object) се могу схватити, ослањајући се на синтаксу, као инстанце (енгл. instance) декларисаних класа. Конкретна структурна променљива је инстанца декларисане структуре. Исто тако, објекат је инстанца декларисане класе. Ову везу класа и објеката треба имати увек у виду јер се у терминологији често занемарује потпуно различит карактер ова два термина. Класе су дакле шеме објеката, а објекти су конкретни подаци у меморији рачунара са припадајућим функцијама дефинисаним у одговарајућим класама.

Конструктори и деструктори

уреди

Конструктор је функција чланица која има исто име као и класа. Улога конструктора је да изврши иницијализацију података чланова класе. За разлику од програмског језика Java, где се такозвани „објекти отпаци“ аутоматски бришу коришћењем такозваног garbage collector-a, у C++-у је неопходно написати функцију која мора да обрише алоцирани меморијски простор из хип меморије. Подразумевајуће функције чланице класе које служе у ову сврху се називају деструктори. C++ има могућност да се при позиву конструктора изврши такозвано копирање објеката. Типови конструктора који имају могућност извршења оваквих операција се називају конструктори копирања.

Конструктор класе је специјална функција чланица класе која се извршава сваки пут када се креира нова инстанца неке класе. Конструктор ће имати исти назив као и сама класа, док повратни тип функције неће бити чак ни void. Конструктори су веома корисни у циљу постављања почетних (иницијалних) вредности одређеним подацима члановима. Комплементарну улогу конструкторима у C++ програмима имају деструктори. Деструктори су функције које се, као и конструктори, позивају аутоматски, али у овом случају при престанку постојања објекта тј. при његовом деструктуирању. Најчешћи задатак деструктора је деалоцирање меморије и реиницијализација променљивих (нпр. бројача објеката одређене класе). У програму се деструктор функције лако уочавају јер им име почиње знаком "~" (тилда), а следи назив класе којој деструктор припада. Деструктор, као и конструктор, не враћа никакву вредност, па се декларише без навођења типа. Деструктор је од велике користи за ослобађање ресурса пре изласка из програма, као што је на пример затварања фајлова, ослобађање динамички заузете меморије итд.

Показивачи на C++ класе

уреди

Објектима неке класе је могуће приступити коришћењем показивача. Једном декларисана, класа постаје валидни тип податка на који можемо усмерити показивач. Декларисање показивача на класу може бити извршено на следећи начин:

Rectangle * prect;

где ће prect бити показивач на објекат класе Rectangle. Показивач на класе се користи на исти начин као и показивач на структуре. Да би се приступило члану класе коришћењем показивача на класу, користи се оператор приступа -> на исти начин како се овај оператор користи код показивача на структуру. Такође, као при раду са свим осталим показивачима, неопходно је иницијализовати показивач пре самог коришћења.

Наслеђивање

уреди

Наслеђивање је једна од најважнијих особина објектно оријентисаног програмирања. Оно омогућава креирање врло сложених класа крећући се од основних класа, што олакшава креирање и одржавање апликације. Ово такође обезбеђује могућност поновног коришћења написаног кода што убрзава само писање апликације.

У C++-у класа може бити изведена из више од једне класе, што значи да може наследити податке и методе из више базних класа истовремено. Да би дефинисали изведену класу, користимо листу извођења којом се специфицирају базне класе.

У C++-у је омогућено вишеструко наслеђивање. Вишеструко наслеђивање омогућава да изведена класа наследи чланове више од једног родитеља. Иако вишеструко наслеђивање на први поглед делује као једноставно проширење једноструког наслеђивања, оно уводи пуно нових проблема које могу значајно да увећају комплексност програма.

Један од проблема вишеструког наслеђивања је двосмисленост, која се јавља у случају када базне класе садрже функције са истим називима. Други, и много озбиљнији је проблем „дијаманта“ који настаје када нека класа наслеђује особине две базне класе, а те базне класе су изведене из исте основне класе. Ово води до појаве такозваног дијамантског облика наслеђивања.

Многи релативно новији језици као што су Јава и C# ограничавају класе на једноструком наслеђивању, али дозвољавају вишеструко наслеђивање интерфејса. Главна идеја онемогућавања вишеструког наследства у овим језицима је чињеница да оно једноставно чини језике превише сложеним, а на крају изазива нове проблема уместо да решава постојеће. Многи аутори и искусни програмери верују да вишеструко наслеђивање треба избегавати по сваку цену због многих потенцијалних проблема које оно доноси. Међутим, постоје ситуације када је вишеструко наслеђивање најбоље решење, али у тим случајевима га треба користити веома промишљено.

C++ стандардна библиотека

уреди

C++ стандардна библиотека (C++ Standard Library) је скуп класа и функција које су написане на изворном језику. C++ стандардна библиотека обезбеђује неколико генеричких контејнера, функција које ангажују и манипулишу овим контејнерима, објекте функција (functors), генеричке стрингове и токове (укључујући стандардни улаз/излаз, а и рад са фајловима), као и стандардне функције за обављање свакодневних задатака као што су проналажење квадрата, корен броја итд. Својства C++ стандардне библиотеке су смештена у именском простору стд. C++ стандардна библиотека се може поделити у два дела:

  • Стандардна библиотека функција (енгл. The Standard Function Library): Ова библиотека се састоји из функција опште намене које су самосталне и које нису део класа, а наслеђена је из C-а.
  • Библиотека OO класа (енгл. The Object Oriented Class Library): Представља колекцију класа и одговарајућих функција чланица.

Стандардна C++ библиотека садржи све елементе C библиотеке, уз мале измене које обезбеђују сигурност употребе типова података (енгл. type safety).

Стандардна библиотека функција се састоји из следећих категорија:

  • Улазно/излазне функције (I/О)
  • Функције за рад са стринговима и карактерима
  • Математичке функције
  • Функције за рад са временом и датумом
  • Функције за динамичко управљање меморијом
  • Остале функције

Стандардна C++ OO библиотека дефинише додатни скуп класа које пружају подршку многобројним свакодневним активностима, укључујући улаз/излаз, рад са стринговима и процесирање бројеве. Ова библиотека се састоји из:

  • Стандардних C++ класа за улаз/излаз
  • Класа за рад са стринговима (стринг)
  • Класа за рад са бројевима
  • STL контејнерских класа
  • STL алгоритама
  • STL функцијских објеката
  • STL итератора
  • STL алокатора
  • Класа за управљање изузецима
  • Библиотека за локализацију
  • Библиотека за разноразну подршку

Шаблони

уреди

Шаблони представљају основ генеричког програмирања, које укључује писање кода у смислу да је функционалност кода независна од коришћених типова података.[5] Шаблон је у ствари формула за креирање генеричких класа или функција. C++ контејнери, као што су итератори, су пример генеричког програмирања коришћењем концепта шаблона. Шаблони се могу користити за дефинисање класа и функција.

Шаблон тј. template у C++-у је један апстрактни рецепт за прављење конкретног кода. Један исти шаблон омогућује да се генерише пуно различитих верзија односно инстанци шаблона. Ово се постиже помоћу шаблонских улазних параметара (тзв. „аргумената“), који функционишу за шаблоне на исти начин како обични параметри функционишу за функције. Али, обични параметри су предвиђени за конкретне објекте тј. конкретне вредности података, а параметри шаблона су предвиђени за типове података и класе. Механизам који C++ нуди за производњу инстанци шаблона је врло важна особина C++-a, која га разликује од многих програмских језика. Овај механизам омогућује аутоматску производњу кода, што битно повећава ефикасност кодирања. Основна форма дефиниције шаблона функције има следећи облик:

{template <class type> ret-type func-name(parameter list){
 // body of function
} }

где је type назив типа податка или класе која ће бити коришћена од стране функције. Овај назив може бити коришћен унутар тела тј. дефиниције функције. Симбол type (углавном се користи ознака Т) је

type parameter, односно „типски параметар“. Овај типски параметар може бити било који уграђени или сложени тип податка.

Генерално гледано, декларација шаблона функције је иста као и обична декларација функције, осим што се испред стави спецификација template<...>, а типски параметар Т се затим може користити уместо обичних типова као у следећем примеру:

{template <class T>
T squareF(T tV) {
    return tV*tV;
} }

Стандардизација C++-а је донела низ промена, а једна од најбитнијих је увођење STL-а, Standard Template Library. STL је колекција шаблона класа и функција дизајнираних да омогуће бољу употребу контејнерских објеката као што су: вектори, листе, сетови, мапе, итд. Класе које могу бити дефинисане из ових шаблона се наравно називају контејнерске класе.

Референце

уреди
  1. ^ „History of C++”. Приступљено 28. 11. 2017. 
  2. ^ „Bjarne Stroustrup's FAQ: "When was C++ invented?". 
  3. ^ Stroustrup, Bjarne. „A History of C ++ : 1979− 1991” (PDF). Архивирано (PDF) из оригинала 2. 2. 2019. г. Приступљено 18. 7. 2013. 
  4. ^ „Bjarne Stroustrup's FAQ – Where did the name "C++" come from?”. Приступљено 16. 1. 2008. 
  5. ^ „C++ Templates”. 

Спољашње везе

уреди