Знаймо

Додати знання

приховати рекламу

Цей текст може містити помилки.

C + +



План:


Введення

C + + - компільований статично типізований мова програмування загального призначення.

Підтримує різні парадигми програмування, поєднує властивості як високорівневих, так і низькорівневих мов [1] [2]. У порівнянні з його попередником - мовою C, - найбільшу увагу приділено підтримці об'єктно-орієнтованого і узагальненого програмування. [2] Назва "C + +" походить від назви мови C, в якому унарний оператор ++ позначає інкремент змінної.

Будучи одним з найбільш популярних мов програмування, [3] [4] C + + широко використовується для розробки програмного забезпечення. Область його застосування включає створення операційних систем, різноманітних прикладних програм, драйверів пристроїв, додатків для вбудованих систем, високопродуктивних серверів, а також розважальних програм (наприклад, відеоігри). Існує декілька реалізацій мови C + + - як безкоштовних, так і комерційних. Найбільш популярні проект GNU, Microsoft, Intel і Embarcadero (Borland). C + + зробив величезний вплив на інші мови програмування, в першу чергу на Java і C #.

При створенні C + + Бьерн Страуструп прагнув зберегти сумісність з мовою C. Безліч програм, які можуть однаково успішно транслюватися як компіляторами C, так і компіляторами C + +, досить велика - почасти завдяки тому, що синтаксис C + + був заснований на синтаксисі C.


1. Історія

Історичний етап розвитку [5] Рік
Мова BCPL 1966
Мова Бі (оригінальна розробка Томпсона під UNIX) 1969
Мова Сі (додавання Рітчі типу і керуючих структур у мову Бі) 1973
Сі з класами 1979
C84 1984
Cfront (випуск E) 1984
Cfront (випуск 1.0) 1985
Поява множинного / віртуального наслідування 1988
Узагальнене програмування (шаблони) 1991
ANSI C + + / ISO-C + + 1996
ISO / IEC 14882:1998 1998
ISO / IEC 14882:2003 2003
C + + / CLI 2005
TR1 2005
C + +11 2011

Мова виникла на початку 1980-х років, коли співробітник фірми Bell Laboratories Бьерн Страуструп придумав ряд удосконалень до мови C під власні потреби. До початку офіційної стандартизації мова розвивалася в основному силами Страуструпа у відповідь на запити програміста спільноти. В 1998 був ратифікований міжнародний стандарт мови C + +: ISO / IEC 14882:1998 "Standard for the C + + Programming Language"; після прийняття технічних виправлень до стандарту в 2003 - нинішня версія цього стандарту - ISO / IEC 14882:2003. [6]

Ранні версії мови, відомі під ім'ям "C з класами", почали з'являтися з 1980. [7] Ідея створення нової мови бере початок від досвіду програмування Страуструпа для дисертації. Він виявив, що мова моделювання Simula має такі можливості, які були б дуже корисні для розробки великого програмного забезпечення, але працює дуже повільно. У той же час мова BCPL досить швидкий, але дуже близький до мов низького рівня і не підходить для розробки великого програмного забезпечення. Страуструп почав працювати в Bell Labs над завданнями теорії черг (у додатку до моделювання телефонних дзвінків). Спроби застосування існуючих у той час мов моделювання виявилися неефективними. Згадуючи досвід своєї дисертації, Страуструп вирішив доповнити мову C (наступник BCPL) можливостями, наявними в мові Симула. Мова C, будучи базовою мовою системи UNIX, на якій працювали комп'ютери Bell, є швидким, багатофункціональним і стерпним. Страуструп додав до нього можливість роботи з класами і об'єктами. В результаті, практичні завдання моделювання виявилися доступними для вирішення як з точки зору часу розробки (завдяки використанню Симула-подібних класів) так і з точки зору часу обчислень (завдяки швидкодії C). На початку в C були додані класи (з інкапсуляцією), похідні класи, сувора перевірка типів, inline-функції і аргументи за умовчанням.

Розробляючи C з класами (пізніше C + +), Страуструп також написав програму cfront - транслятор, що переробляє вихідний код C з класами у вихідний код простого C. Нова мова, несподівано для автора, придбав велику популярність серед колег і незабаром Страуструп вже не міг особисто підтримувати його, відповідаючи на тисячі питань.

В 1983 відбулося перейменування мови з C з класами в C + +. Крім того, в нього були додані нові можливості, такі як віртуальні функції, перевантаження функцій і операторів, посилання, константи, користувальницький контроль над управлінням вільною пам'яттю, поліпшена перевірка типів і новий стиль коментарів ( //). Його перший комерційний випуск відбувся в жовтні 1985. У 1985 році вийшло перше видання також "Мови програмування C + +", що забезпечує перший опис цієї мови, що було надзвичайно важливо через відсутність офіційного стандарту. В 1989 відбувся вихід C + + версії 2.0. Його нові можливості включали множинне спадкування, абстрактні класи, статичні функції-члени, функції-константи і захищені члени.

В 1990 вийшло "коментувати посібник по C + +", покладене згодом в основу стандарту. Останнє оновлення включали шаблони, винятки, простору імен, нові способи приведення типів і булевський тип.

Стандартна бібліотека C + + також розвивалася разом з ним. Першим додаванням до стандартної бібліотеці C + + стали потоки введення / виводу, що забезпечують кошти для заміни традиційних функцій C printf і scanf. Пізніше самим значним розвитком стандартної бібліотеки стало включення до неї Стандартної бібліотеки шаблонів.

Ніхто не володіє правами на мову C + +, він є вільним. Проте сам документ стандарту мови (за винятком чернеток) не доступний безкоштовно.


1.1. Стандартизація мови

В 1998 був опублікований стандарт мови ISO / IEC 14882:1998 (відомий як C + +98), [8] розроблений комітетом з стандартизації C + + ( ISO / IEC JTC1/SC22/WG21 Working Group).

В 2003 був опублікований стандарт мови ISO / IEC 14882:2003, де були виправлені виявлені помилки і недоліки попередньої версії стандарту.

В 2005 був випущений звіт "Library Technical Report 1" (коротко званий TR1). Не будучи офіційно частиною стандарту, звіт описує розширення стандартної бібліотеки, які, як очікувалося авторами, повинні бути включені в наступну версію мови C + +. Ступінь підтримки TR1 поліпшується майже у всіх підтримуваних компіляторах мови C + +.

З 2009 велася робота по оновленню попереднього стандарту, попередньої версією нового стандрата спершу був C + +99, а через рік C + +0 x, сьогодні - C + +11, куди були включені додатки ядро мови та розширення стандартної бібліотеки, в тому числі більшу частину TR1.


1.2. Історія назви

Назва C + + було придумано Ріком Массітті (Rick Mascitti) і вперше було використано в грудні 1983. Раніше, на етапі розробки, нова мова називався "C з класами". [7]

Ім'я мови, вийшло в результаті, походить від оператора унарний постфіксной інкремента C ++ (збільшення значення змінної на одиницю). Ім'я C + не було використано тому, що є синтаксичної помилкою в C і, крім того, це ім'я було зайнято іншою мовою. Мова також не був названий D, оскільки "є розширенням C і не намагається усувати проблеми шляхом видалення елементів C". [7]


2. Філософія C + +

У книзі " Дизайн і еволюція C + + " Бьерн Страуструп описує принципи, яких він дотримувався при проектуванні C + +. [9] Ці принципи пояснюють, чому C + + саме такий, яким він є. Деякі з них:

  • Отримати універсальна мова зі статичними типами даних, ефективністю і переносимістю мови C.
  • Безпосередньо і всебічно підтримувати безліч стилів програмування, у тому числі процедурне програмування, абстракцію даних, об'єктно-орієнтоване програмування та узагальнене програмування.
  • Дати програмісту свободу вибору, навіть якщо це дасть йому можливість вибирати неправильно.
  • Максимально зберегти сумісність з C, тим самим роблячи можливим легкий перехід від програмування на C.
  • Уникнути різночитань між C і C + +: будь-яка конструкція, допустима в обох мовах, повинна в кожному з них позначати одне й те саме і приводити до одного й того ж поведінки програми.
  • Уникати особливостей, які залежать від платформи або не є універсальними.
  • Ніяке мовний засіб не повинно призводити до зниження продуктивності програм, які не використовують його.
  • Не вимагати занадто ускладненою середовища програмування.

3. Огляд мови

Стандарт C + + на 2003 складається з двох основних частин: опис ядра мови і опис стандартної бібліотеки.

Крім того, існує величезна кількість бібліотек C + +, що не входять в стандарт. У програмах на C + + можна використовувати багато бібліотек C.

Стандартизація визначила мову програмування C + +, однак за цією назвою можуть ховатися також неповні, обмежені, достандартние варіанти мови. Перший час мова розвивалася поза формальними рамками, спонтанно, у міру вставали перед ним завдань. Розвитку мови супроводив розвиток крос-компілятора cfront. Нововведення в мові відбивалися в зміні номера версії кросс-компілятора. Ці номери версій кросс-компілятора розповсюджувалися і на саму мову, але стосовно теперішнього часу мову про версії мови C + + не ведуть.


3.1. Необ'ектно-орієнтовані можливості

У цьому розділі описуються можливості, безпосередньо не пов'язані з об'єктно-орієнтованим програмуванням (ООП), але багато з них, однак, особливо важливі в поєднанні з ООП.

3.1.1. Коментарі

С + + підтримує, як коментарі в стилі C

/* это комментарий */

, Так і однорядкові

// вся оставшаяся часть строки является комментарием

, Де // позначає початок коментаря, а найближчий наступний символ нового рядка, який не передуючи символом \ (або еквівалентним йому позначенням ??/), вважається закінченням коментар.

3.1.2. Типи

У C + + доступні наступні вбудовані типи:

  • Символьні: char, wchar_t.
  • Цілочисельні знакові: signed char, short int, int, long intlong long int, в стандарті C + +11).
  • Цілочисельні беззнакові: unsigned char, unsigned short int, unsigned int, unsigned long int.
  • З плаваючою точкою: float, double, long double.
  • Логічний: bool, що має значення true і false.

Операції порівняння повертають тип bool. Вирази в дужках після if, while приводяться до типу bool. [10]

Функції можуть приймати аргументи за посиланням. Наприклад, функція void f(int &x) {x=3;} присвоює своєму аргументу значення 3. Функції також можуть повертати результат за посиланням, і посилання можуть бути поза всяким зв'язком з функціями. Наприклад, {double &b=a[3]; b=sin(b);} еквівалентно a[3]=sin(a[3]);. При програмуванні посилання певною мірою схожі з покажчиками, з такими особливостями: перед використанням посилання повинне бути инициализирована; посилання довічно указує на один і той же адресу; у виразі посилання позначає безпосередньо той об'єкт або ту функцію, на яку вона вказує, звернення ж до об'єкта або функції через вказівник вимагає разименованія покажчика . Існують і інші відмінності у використанні покажчиків і посилань. Концептуально посилання - інше ім'я змінної або функції, інша назва одного й того-ж адреси, Сущетсвует лише тільки в тексті програми, замінить Вашу при компіляції, а покажчик - змінна, що зберігає адресу, до якого звертаються.


3.1.3. Різне

  • Специфікатор inline дозволяє оголошувати inline-функції. Функція, визначена всередині тіла класу, є inline за замовчуванням. Спочатку inline-функції замислювалися як функції, що є хорошими кандидатами на оптимізацію, при якій в місцях звернення до функції компілятор вставить тіло цієї функції, а не код виклику. Насправді компілятор не зобов'язаний реалізовувати підстановку тіла для inline-функцій, але може, виходячи із заданих критеріїв оптимізації, виконувати підстановку тіла для функцій, які не оголошені як inline. Мабуть, найбільш значущою особливістю inline-функції є те, що вона може багаторазово визначатися в декількох одиницях трансляції (при цьому inline-функція повинна бути визначена в усіх одиницях трансляції, де вона використовується), в той час як функція, яка не є inline, може визначатися в програмі не більше одного разу. Приклад:

inline double Sqr(double x) {return x*x;}.

  • Описувач volatile використовується в описі змінних та інформує компілятор, що значення даної змінної може бути змінено спосіб, який компілятор не в змозі відстежити. Для змінних, оголошених volatile, компілятор не повинен застосовувати засоби оптимізації, що змінюють положення змінної в пам'яті (наприклад, що поміщають її в регістр) або покладаються на незмінність значення змінної у проміжку між двома присвоювання їй значення.
  • Якщо описана структура, клас, об'єднання ( union) або перерахування ( enum), її ім'я є ім'ям типу, наприклад:
 struct  Time  {  int  hh, mm, ss  ;  }  ;  Time t1, t2  ; 
 namespace  Foo  {  const  int  x  =  5  ;  typedef  int  **  T  ;  void  f  (  int  y  )  {  return  y  *  x  }  ;  double  g  (  T  )  ;  ...  } 

то поза фігурних дужок слід звертатися до T, x, f, g як Foo:: T, Foo:: x, Foo:: f і Foo:: g відповідно. Якщо в якомусь файлі потрібно звернутися до них безпосередньо, можна написати

 using  namespace  Foo  ; 

Або ж

 using  Foo  ::  T  ; 

Простору імен потрібні, щоб не виникало колізій між пакетами, що мають співпадаючі імена глобальних змінних, функцій і типів. Спеціальним випадком є ​​безіменний простір імен

 namespace  {  ...  } 

Всі імена, описані в ньому, доступні в поточній одиниці трансляції і більше ніде.

  • Один або декілька останніх аргументів функції можуть задаватися за умовчанням. Наприклад, якщо функція описана як void f(int x, int y=5, int z=10), виклики f(1), f(1,5) і f(1,5,10) еквівалентні.
  • При описі функцій відсутність аргументів в дужках означає, на відміну від C, що аргументів немає, а не те, що вони невідомі. Якщо аргументи невідомі, треба користуватися трьома крапками, наприклад, int printf(const char* fmt, ...).
  • Усередині структури або класу можна описувати вкладені типи, як через typedef, так і через опис інших класів, а також перерахувань. Для доступу до таких типів поза класом, до імені типу додається ім'я структури або класу і дві двокрапки:
 struct  S  {  typedef  int  **  T  ;  T x  ;  }  ;  S  ::  T  y  ; 
  • Можуть бути декілька функцій з одним і тим же ім'ям, але різними типами або кількістю аргументів ( перевантаження функцій; при цьому тип значення на перевантаження не впливає). Наприклад, цілком можна писати:
 void  Print  (  int  x  )  ;  void  Print  (  double  x  )  ;  void  Print  (  int  x,  int  y  )  ; 
  • Сенс деяких операторів стосовно користувальницьким типами можна визначати через оголошення відповідних операторних функцій. Наприклад, так:
 struct  Date  {  int  day, month, year  ;  }  ;  void  operator  + +  (  struct  Date  &  date  )  ; 

Операторні функції багато в чому схожі з звичайними (неоператорнимі) функціями. За винятком операторів new, new[], delete і delete[], не можна перевизначати поведінку операторів для вбудованих типів (скажімо, перевизначати множення значень типу int), не можна вигадувати нові оператори, яких немає в C + + (скажімо, **), не можна міняти кількість операндів, передбачене для оператора, а також не можна змінювати існуючі пріоритети і асоціативність операторів (скажімо, у виразі a+b*c спочатку виконуватиметься множення, а потім складання, до яких би типів не належали a, b і c). Можна перевизначити операції [] (з одним параметром) і () (з будь-яким числом параметрів).

  • Додані шаблони ( template). Наприклад, template T Min(T x, T y) {return x визначає функцію Min для будь-яких типів. Шаблони можуть задавати не тільки функції, але і типи. Наприклад, template struct Array{int len; T* val;}; визначає масив значень будь-якого типу, після чого ми можемо писати Array x;
  • На додаток до функцій malloc і free введені операторні функції operator new, operator new[], operator delete і operator delete[], а також оператори new, new[], delete і delete[]. Якщо T - довільний об'єктний тип, який не є типом масиву, X - довільний об'єктний тип і A - тип масиву з деякої кількості n елементів, що мають тип X, то
    • new T виділяє пам'ять (за допомогою виклику функції operator new), достатню для розміщення одного об'єкту типу Т, можливо, ініціалізує об'єкт в цій пам'яті, і повертає покажчик типу Т* (наприклад, Т* p = new T).
    • new X[n] і new A виділяють пам'ять (за допомогою виклику функції operator new[]), достатню для розміщення n об'єктів типу X, можливо, ініціалізують кожен об'єкт в цій пам'яті, і повертають покажчик типу X* (наприклад, X* p = new X[n]).
    • delete p - руйнує об'єкт (який не є масивом), на який посилається вказівник p, і звільняє область пам'яті (за допомогою виклику функції operator delete), раніше виділену для нього new-виразом.
    • delete [] p - руйнує кожен об'єкт в масиві, на який посилається вказівник p, і звільняє область пам'яті (за допомогою виклику функції operator delete[]), раніше виділену для цього масиву new-виразом.

Операція delete перевіряє, що її аргумент не NULL, інакше вона нічого не робить. Для ініціалізації об'єкта non-POD класового типу new-вираз викликає конструктор; для знищення об'єкта класового типу delete-вираз викликає деструктор (див. нижче).


3.2. Об'єктно-орієнтовані особливості мови

C + + додає до C об'єктно-орієнтовані можливості. Він вводить класи, які забезпечують три найважливіші властивості ООП : інкапсуляцію, успадкування і поліморфізм.

У стандарті C + + під класом (class) мається на увазі користувальницький тип, оголошений з використанням одного з ключових слів class, struct або union, під структурою (structure) мається на увазі клас, визначений через ключове слово struct, і під об'єднанням (union) мається на увазі клас, визначений через ключове слово union.


3.2.1. Опис функцій в тілі класу

В тілі класу можна вказати тільки заголовок функції, а можна описати всю функцію (див. приклад з функцією Alloc нижче. У цьому випадку вона вважається вбудованою ( inline))

3.2.2. Константні функції-члени

Нестатичні функції-члени (і лише вони) можуть мати описувач const

 class  Array  {  ...  inline  double  operator  [  ]  (  int  n  )  const  ; 

Такі функції не мають права змінювати поля класу (окрім полів, визначених як mutable). Якщо вони намагаються це зробити, компілятор повинен видати повідомлення про помилку.

3.2.3. Спадкування

У C + + при спадкуванні одного класу від іншого успадковується реалізація класу, плюс клас-спадкоємець може додавати свої поля і функції або перевизначати функції базового класу. Множинне успадкування дозволено.

Конструктор спадкоємця викликає конструктори базових класів, а потім конструктори нестатичні членів-даних, що є екземплярами класів. Деструктор працює в зворотному порядку.

Спадкування буває публічним, захищеним і закритим (тобто закритого типу):

Доступ члена базового класу / режим спадкування private-член protected-член public-член
private-спадкування недоступний private private
protected-спадкування недоступний protected protected
public-спадкування недоступний protected public

Спадкоємець - це більше ніж базовий клас, тому, якщо спадкування відкрите, то він може використовуватися скрізь, де використовується базовий клас, але не навпаки.


3.2.4. Поліморфізм

Поліморфізмом в програмуванні називається перевизначення спадкоємцем функцій-членів базового класу, наприклад:

 class  Figure  {  ...  void  Draw  (  )  const  ;  ...  }  ;  class  Square  :  public  Figure  {  ...  void  Draw  (  )  const  ;  ...  }  ;  class  Circle  :  public  Figure  {  ...  void  Draw  (  )  const  ;  ...  }  ; 

Яка саме з функцій буде викликана - Figure::Draw(), Square::Draw() або Circle::Draw() - визначається під час компіляції. Наприклад:

 Circle  *  c  =  new  Circle  (  0  ,  0  ,  5  )  ;  Figure  *  f  =  c  ;  / / Все ok: Figure - базовий клас для Circle  c  -  >  Draw  (  )  ;  f  -  >  Draw  (  )  ;  / / Покажчики один одному рівні, але для f буде викликана інша функція, ніж для c 

Незважаючи на те, що обидва покажчика вказують на один і той же об'єкт класу Circle, для c буде викликана Circle::Draw(), а для f - Figure::Draw(), оскільки f - покажчик на об'єкт класу Figure. Такий поліморфізм називається статичним.

Але в C + + є і динамічний поліморфізм, коли викликається, визначається під час виконання. Для цього функції-члени базового класу повинні бути оголошені віртуальними.

 class  Figure  {  ...  virtual  void  Draw  (  )  const  ;  ...  }  ;  class  Square  :  public  Figure  {  ...  void  Draw  (  )  const  ;  ...  }  ;  class  Circle  :  public  Figure  {  ...  void  Draw  (  )  const  ;  ...  }  ;  Figure  *  figures  [  10  ]  ;  figures  [  0  ]  =  new  Square  (  1  ,  2  ,  10  )  ;  figures  [  1  ]  =  new  Circle  (  3  ,  5  ,  8  )  ;  ...  for  (  int  i  =  0  ;  i  <  10  ;  i  + +  )  figures  [  i  ]  -  >  Draw  (  )  ; 

У цьому випадку для кожного елемента масиву буде викликана Square::Draw() або Circle::Draw() залежно від виду фігури.

Чисто віртуальною функцією називається віртуальна функція-член, яка оголошена зі специфікатором = 0 :

 class  Figure  {  ...  virtual  void  Draw  (  )  const  =  0  ;  )  ; 

Чисто віртуальна функція може бути залишена без визначення, крім випадку, коли потрібно провести її виклик.

Абстрактним класом називається такий, у якого є хоча б одна чисто віртуальна функція-член. Об'єкти таких класів створювати заборонено. Абстрактні класи часто використовуються як інтерфейси. На відміну від чистих інтерфейсів інших мов, абстрактні класи С + + можуть мати невіртуальний функції та члени-дані.


3.2.5. Інкапсуляція

Основним способом організації інформації в C + + є класи. На відміну від структури ( struct) мови C, яка може складатися тільки з полів і вкладених типів, клас ( class) C + + може складатися з полів, вкладених типів і функцій-членів (member functions). Інкапсуляція в С + + реалізується через вказівку рівня доступу до членів класу: вони бувають публічними (відкритими, public), захищеними ( protected) і власними (закритими, приватними, private). У C + + структури формально відрізняються від класів лише тим, що за замовчуванням члени та базові класи у структури публічні, а у класу - власні.

Доступ private protected public
Сам клас да да да
Друзі да да да
Спадкоємці немає да да
Ззовні немає немає да

Перевірка доступу відбувається під час компіляції, спроба звернення до недоступного члену класу викличе помилку компіляції.

Приклад класу, що реалізовує одновимірний масив (це просто ілюстрація, а не зразок дизайну!):

 class  Array  {  public  :  Array  (  )  :  len  (  0  )  , Val  (  NULL  )  {  }  Array  (  int  _len  )  :  len  (  _len  )  {  val  =  new  double  [  _len  ]  ;  }  Array  (  const  Array  &  a  )  ;  ~ Array  (  )  {  Free  (  )  ;  }  inline  const  double  &  Elem  (  int  i  )  const  {  return  val  [  i  ]  ;  }  inline  void  ChangeElem  (  int  i,  double  x  )  {  val  [  i  ]  =  x  ;  }  protected  :  void  Alloc  (  int  _len  )  {  if  (  len  ==  0  )  Free  (  )  ;  len  =  _len  ;  val  =  new  double  [  len  ]  ;  }  void  Free  (  )  {  delete  [  ]  val  ;  len  =  0  ;  }  int  len  ;  double  *  val  ;  }  ; 

Тут клас Array має 2 публічних функції-члена, 2 захищених поля, 3 публічних конструктора і публічний деструктор. Описувач inline означає підказку компілятору, що замість виклику функції її код слід вмонтувати в точку виклику, ніж часто можна досягти більшої ефективності.


3.2.6. Друзі

Функції-друзі - це функції, які не є функціями-членами і тим не менш мають доступ до захищених і закритим членів класу. Вони повинні бути оголошені в тілі класу як friend. Наприклад:

 class  Matrix  {  ...  friend  Matrix Multiply  (  Matrix m1, Matrix m2  )  ;  ...  }  ;  Matrix Multiply  (  Matrix m1, Matrix m2  )  {  ...  } 

Тут функція Multiply може звертатися до будь-яких полях і функцій-членів класу Matrix.

Існують також класи-друзі. Якщо клас A - друг класу B, то всі його власні (не успадковані) функції-члени можуть звертатися до будь-яких членів класу B. Наприклад:

 class  Matrix  {  ...  friend  class  Vector  ;  ...  }  ; 

Проте в C + + не діє правило "друг мого друга - мій друг".

За діючим стандартом C + + вкладений клас не має прав доступу до закритих членам осяжний класу і не може бути оголошений його другом (останнє випливає з визначення терміна друг як нечлена класу). У майбутньому стандарті C + +0 x ці обмеження будуть усунені. У даному відношенні сучасні версії компіляторів VC + +, GNU C + + і Comeau C + + навіть з відключеними розширеннями слідують новими правилами, сформульованим в останніх версіях чернетки C + +0 x.


3.2.7. Конструктори і деструктори

У класах завжди є спеціальні функції - конструктори і деструктори, які можуть бути оголошені явно чи неявно.

Конструктор викликається для ініціалізації об'єкта (відповідного типу) при його створенні, а деструктор - для знищення об'єкта. Зокрема, конструктор може бути викликаний для конвертування до класового типу.

Конструктори позначаються як однойменні класу функції (наприклад, Array::Array), деструктори - як ім'я класу, упереджені тильдою (наприклад, Array::~Array). Для конструкторів і деструкторів не можна вказувати тип повернення. Деструкція не можна оголошувати як приймаюче аргументи. Клас може мати скільки завгодно конструкторів (з різними наборами параметрів), у тому числі шаблонних, і тільки один (причому нешаблонний) деструктор.

Конструктор без параметрів або конструктор, всі параметри якого мають аргументи за умовчанням, називається конструктором за умовчанням, нешаблонний конструктор з першим параметром-посиланням на той же клас (наприклад, Array::Array(const Array&)) і іншими параметрами (якщо такі є) , що мають аргументи за умовчанням, - конструктором копіювання, він викликається при створенні нового об'єкта, що є копією вже існуючого об'єкта:

 Array a  (  5  )  ;  / / Викликається Array:: Array (int)  Array b  ;  / / Викликається Array:: Array ()  Array c  (  a  )  ;  / / Викликається Array:: Array (const Array &)  Array d  =  a  ;  / / Те ж саме  b  =  c  ;  / / Відбувається виклик оператора =  / / Якщо він не визначений (як в даному випадку), то викликається згенерований компілятором оператор присвоювання, який  / / Здійснює копіювання базових підоб'єктів і почленное копіювання нестатичні членів-даних.  / / Як правило конструктор копій і оператор присвоювання перевизначаються попарно 

Якщо в класі немає явно оголошених конструкторів, то клас має неявно оголошений конструктор без параметрів. Якщо в класі немає явно оголошених копіюють конструкторів, то клас має неявно оголошений копіює конструктор. Якщо в класі немає явно оголошеного деструктора, то клас має неявно оголошений деструктор.


3.2.8. Перевантаження операторів

Функції-члени можуть бути операторами:

 class  Array  {  ...  inline  double  &  operator  [  ]  (  int  n  )  {  return  val  [  n  ]  ;  } 

І далі

 Array a  (  10  )  ;  ...  double  b  =  a  [  5  ]  ; 

4. Стандартна бібліотека

Стандартна бібліотека С + + включає в себе як сутності, специфічні для С + +, так і, частково, стандартну бібліотеку C з невеликими змінами , Які роблять її більш відповідною для мови C + + [джерело не вказано 454 дні]. Стандарт C + + містить нормативну посилання на стандарт C від 1990 і не визначає самостійно ті функції стандартної бібліотеки, які запозичуються із стандартної бібліотеки C. Доступ до можливостей стандартної бібліотеки C + + забезпечується за допомогою включення в програму (за допомогою директиви #include) відповідних стандартних заголовків файлів. Всього в стандарті C + + визначено 50 таких файлів.

Для використання наступних функцій стандартної бібліотеки

 void  *  operator  new  (  std  ::  size_t  )  throw  (  std  ::  bad_alloc  )  ;  void  *  operator  new  [  ]  (  std  ::  size_t  )  throw  (  std  ::  bad_alloc  )  ;  void  operator  delete  (  void  *  )  throw  (  )  ;  void  operator  delete  [  ]  (  void  *  )  throw  (  )  ; 

підключення будь-яких заголовних файлів не потрібно.

Стандартна бібліотека C + + складається з наступних розділів:


4.1. Підтримка мови

  • - описи стандартних типів
  • , , - засоби доступу до властивостей реалізації мови
  • - кошти завершення програми
  • - управління динамічним виділенням пам'яті
  • - отримання інформації про типи під час виконання програми
  • - обробка виключень
  • , , , , - інші кошти виконавчі

4.2. Засоби діагностики

  • - стандартні класи виключень
  • - діагностичні затвердження
  • - засоби роботи з кодами помилок

4.3. Кошти загального призначення

  • - узагальнені оператори і пари
  • - стандартні узагальнені функтори, операції зв'язування аргументів і функціональні адаптери
  • - засоби управління пам'яттю, у тому числі аллокатор, спеціальні алгоритми і клас auto_ptr
  • - типи і функції для роботи з датами і часом

4.4. Засоби роботи з текстовими рядками

  • - характеристики символів
  • - рядкові класи
  • , , , , - засоби роботи з символьними рядками, завершуються нулем

4.5. Засоби інтернаціоналізації

  • - об'єкти національно-культурного контексту
  • - об'єкти національно-культурного контексту стандартної бібліотеки C

4.6. Контейнери

  • , , , , - послідовні контейнери і контейнерні адаптери
  • , , - асоціативні контейнери

4.7. Ітератори

  • - характеристики і стандартні теги ітераторів, зворотні ітераторние адаптери та ітератори вставки, ітератори потоків вводу-виводу

4.8. Алгоритми

  • - немодіфіцірующіе алгоритми, модифікуючі алгоритми, алгоритми сортування та впорядкованих інтервалів
  • - алгоритми стандартної бібліотеки мови C

4.9. Чисельні алгоритми

  • - клас комплексних чисел
  • - чисельні масиви
  • - узагальнені чисельні алгоритми
  • , - математичні функції стандартної бібліотеки мови C

4.10. Засоби вводу-виводу

  • - попередні оголошення типів
  • - класи стандартних потоків введення-виведення
  • - базові класи бібліотеки
  • - класи потокових буферів
  • , , - засоби форматування, потокові маніпулятори
  • , - рядкові потоки
  • , , - файлові потоки

4.11. Реалізації

STL до включення в стандарт C + + була сторонньою розробкою, на початку - фірми HP, а потім SGI. Стандарт мови не називає її "STL, оскільки ця бібліотека стала невід'ємною частиною мови, проте багато людей до сих пір використовують цю назву, щоб відрізняти її від іншої частини стандартної бібліотеки (потоки введення / виводу ( iostream), підрозділ C та інші).

Проект під назвою STLport [11], заснований на SGI STL, здійснює постійне оновлення STL, IOstream і рядкових класів. Деякі інші проекти також займаються розробкою приватних застосувань стандартної бібліотеки.


5. Відмінності С + + від C

5.1. Нові можливості в порівнянні з C

Нововведеннями C + + порівняно з C є:

Нові можливості C + + включають оголошення у вигляді виразів, перетворення типів у вигляді функцій, оператори new і delete, тип bool, посилання, розширене поняття константності, підставляються функції, аргументи за умовчанням, перевизначення, простори імен, класи (включаючи і всі пов'язані з класами можливості , такі як успадкування, функції-члени, віртуальні функції, абстрактні класи і конструктори), перевизначення операторів, шаблони, оператор ::, обробку винятків, динамічну ідентифікацію і багато іншого. Мова C + + також у багатьох випадках суворіше ставиться до перевірки типів, ніж C.

У C + + з'явилися коментарі у вигляді подвійної косої межі ( //), які були в попереднику C - мовою BCPL.

Деякі особливості C + + пізніше були перенесені в C, наприклад, ключові слова const і inline, оголошення в циклах for і коментарі в стилі C + + ( //). У більш пізніх реалізаціях C також були представлені можливості, яких немає в C + +, наприклад макроси va_arg і покращена робота з масивами-параметрами.


5.2. C + + не включає в себе C

Незважаючи на те, що більша частина коду C буде справедлива і для C + +, C + + не є надбезліччю C і не включає його в себе. Існує і такий вірний для C код, який невірний для C + +. Це відрізняє його від Objective C, ще одного удосконалення C для ООП, як раз є надбезліччю C.

Існують і інші відмінності. Наприклад, C + + не дозволяє викликати функцію main() всередині програми, тоді як в C ця дія правомірно. Крім того, C + + більш суворий у деяких питаннях, наприклад, він не допускає неявне приведення типів між непов'язаними типами покажчиків і не дозволяє використовувати функції, які ще не оголошені.

Більше того, код, вірний для обох мов, може давати різні результати залежно від того, компілятором якої мови він відтранслювати. Наприклад, на більшості платформ наступна програма друкує "С", якщо компілюється компілятором C, і "C + +" - якщо компілятором C + +. Так відбувається через те, що символьні константи в C (наприклад, 'a') мають тип int, а в C + + - тип char, а розміри цих типів звичайно розрізняються.

 # Include   int  main  (  )  {  printf  (  "% S  \ N  "  ,  (  sizeof  (  'A'  )  ==  sizeof  (  char  )  )  ?  "C + +"  :  "C"  )  ;  return  0  ;  } 

6. Подальший розвиток

Поточний стандарт мови ISO / IEC 14882:2003 (E) був прийнятий в 2003. Неофіційно його позначають як C + +03. Наступна версія стандарту має неофіційне позначення C + +11.

C + + продовжує розвиватися, щоб відповідати сучасним вимогам. Одна з груп, що займаються мовою C + + в його сучасному вигляді і що направляють комітету із стандартизації C + + поради з його поліпшення - це Boost. Наприклад, один із напрямів діяльності цієї групи - вдосконалення можливостей мови шляхом додавання в нього особливостей метапрограмування.

Стандарт C + + не описує способи іменування об'єктів, деякі деталі обробки винятків і інші можливості, пов'язані з деталями реалізації, що робить несумісним об'єктний код, створений різними компіляторами. Однак для цього третіми особами створена безліч стандартів для конкретних архітектур і операційних систем.


6.1. Ключове слово export

Однією з точок спотикання в цьому питанні є ключове слово export, використовуване також і для розділення оголошення і визначення шаблонів.

Першим компілятором, що підтримує export в шаблонах, став Comeau C + + на початку 2003 (через 5 років після виходу стандарту C + +98). В 2004 бета-версія компілятора Borland C + + Builder X також почала його підтримку.

Обидва цих компілятора засновані на фронт-енді EDG. Інші компілятори, такі як Microsoft Visual C + + або GCC (GCC 3.4.4), взагалі цього не підтримують. Герб Саттер, секретар комітету з стандартизації C + +, рекомендував прибрати export з майбутніх версій стандарту унаслідок серйозних складнощів в повноцінній реалізації, проте згодом його вирішили залишити. Підтримують export : Microsoft Visual C + + 7.0, GCC 3.4.4, Microsoft Visual Studio 2010 і інші.

Із списку інших проблем, пов'язаних з шаблонами, можна привести питання конструкцій часткової спеціалізації шаблонів, які погано підтримувалися протягом багатьох років після виходу стандарту C + +.


7. Приклади програм на C + +

7.1. Приклад № 1

Це приклад програми, яка нічого не робить. Вона починає виконуватися і негайно завершується. Вона складається з основного потоку: функції main(), яка позначає точку початку виконання програми на C + +.

 int  main  (  )  {  return  0  ;  } 

Стандарт C + + вимагає, щоб функція main() повертала тип int. Програма, яка має інший тип значення функції main(), не відповідає стандарту C + +.

Стандарт не говорить про те, що насправді означає повертається значення функції main(). Традиційно воно інтерпретується як код повернення програми. Стандарт гарантує, що повернення 0 з функції main() показує, що програма була завершена успішно.

Завершення програми на C + + з помилкою традиційно позначається шляхом повернення ненульового значення.


7.2. Приклад № 2

Ця програма також нічого не робить, але більш лаконічна.

 int  main  (  )  {  } 

У C + + (як і в C), якщо виконання програми доходить до кінця функції main(), то це еквівалентно return 0;. Це невірно для будь-якої іншої функції окрім main().

7.3. Приклад № 3

Це приклад програми Hello World, яка виводить повідомлення, використовуючи стандартну бібліотеку, і завершується.

 # Include  / / це необхідно для std:: cout і std:: endl і для оператора <<  int  main  (  )  {  std  ::  cout  <<  "Hello, world!"  <<  std  ::  endl  ;  return  0  ;  } 

7.4. Приклад № 4

Сучасний C + + дозволяє вирішувати простим способом і складніші завдання. Цей приклад демонструє крім усього іншого використання контейнерів стандартної бібліотеки шаблонів ( STL).

 # Include  / / для використання std:: cout  # Include  / / для std:: vector <>  # Include  / / для std:: map <> і std:: pair <>  # Include  / / для std:: for_each ()  # Include  / / для std:: string  using  namespace  std  ;  / / Використовуємо простір імен "std"  void  display_item_count  (  pair  <  string  const  , Vector  <  string  >  >  const  &  person  )  {  / / Person - це пара двох об'єктів: person.first - це його ім'я,  / / Person.second - це список його предметів (вектор рядків)  cout  <<  person.  first  <<  "Is carrying"  <<  person.  second  .  size  (  )  <<  "Items"  <<  endl  ;  }  int  main  (  )  {  / / Оголошуємо карту із строковими ключами і даними у вигляді векторів рядків  map  <  string, vector  <  string  >  >  items  ;  / / Додамо в цю карту пару чоловік і дамо їм кілька предметів  items  [  "Anya"  ]  .  push_back  (  "Scarf"  )  ;  items  [  "Dmitry"  ]  .  push_back  (  "Tickets"  )  ;  items  [  "Anya"  ]  .  push_back  (  "Puppy"  )  ;  / / Переберемо усі об'єкти в контейнері  for_each  (  items.  begin  (  )  , Items.  end  (  )  , Display_item_count  )  ;  } 

У цьому прикладі для простоти використовується директива використання простору імен, у цій же програмі зазвичай рекомендується використовувати об'яви, які акуратніше директив:

 # Include   int  main  (  )  {  using  std  ::  vector  ;  vector  <  int  >  my_vector  ;  } 

Тут директива поміщена в область функції, що зменшує шанси зіткнень імен (це і стало причиною введення в мову просторів імен). Використання оголошень, зливають різні простору імен в одне, руйнує саму концепцію простору імен. [джерело не вказано 656 днів]


7.5. Приклад № 5

Популярні бібліотеки boost в поєднанні зі стандартними засобами мови дозволяють дуже лаконічно і наочно записувати код. У наведеному нижче прикладі обчислюється скалярний добуток векторів непарних чисел і квадратів. У коді вектора значень представлені ледачими STL-подібними послідовностями.

 # Include   # Include   # Include   # Include   int  odd  (  int  i  )  {  return  2  *  i  +  1  ;  }  int  square  (  int  i  )  {  return  i  *  i  ;  }  typedef  boost  ::  counting_iterator  <  int  >  counter  ;  typedef  boost  ::  transform_iterator  <  int  (  *  )  (  int  )  , Counter  >  transformer  ;  transformer odds  (  int  n  )  {  return  transformer  (  counter  (  n  )  , Odd  )  ;  }  transformer squares  (  int  n  )  {  return  transformer  (  counter  (  n  )  , Square  )  ;  }  int  main  (  )  {  using  namespace  std  ;  cout  <<  "Enter vector length:"  ;  int  n  ;  cin  >>  n  ;  cout  <<  inner_product  (  odds  (  0  )  , Odds  (  n  )  , Squares  (  0  )  ,  0  )  <<  endl  ;  } 

Даний приклад демонструє так званий "плоский" стиль запису. Ця назва пов'язана з тим, що алгоритми STL дозволяють записувати код без циклів, відповідно ширина відступів в відформатованому коді приблизно постійна. Прихильники такого підходу вважають, що програмістові, знайомому зі стандартною бібліотекою С + +, досить рядки з викликом inner_product(), щоб зрозуміти, що робить програма. З цієї точки зору виклик inner_product близький до словесного опису завдання: "вирахувати скалярний добуток векторів непарних чисел і квадратів для значень від нуля до n".


8. Переваги мови та її критика

Перш за все, необхідно підкреслити, що оцінювати достоїнства і, особливо, недоліки C + + необхідно в контексті тих принципів, на яких будувався мову, і вимог, які до нього спочатку висувалися.

8.1. Переваги

C + + - надзвичайно потужна мова, що містить засоби створення ефективних програм практично будь-якого призначення, від низькорівневих утиліт і драйверів до складних програмних комплексів різного призначення. Зокрема:

  • Підтримуються різні стилі та технології програмування, включаючи традиційне директивне програмування, ООП, узагальнене програмування, метапрограмування (шаблони, макроси).
  • Передбачуване виконання програм є важливою перевагою для побудови систем реального часу. Весь код, неявно генерований компілятором для реалізації мовних можливостей (наприклад, при перетворенні змінної до іншого типу), визначений у стандарті. Також суворо визначені місця програми, в яких цей код виконується. Це дає можливість заміряти або розраховувати час реакції програми на зовнішню подію.
  • Автоматичний виклик деструкторів об'єктів при їх знищенні, причому в порядку, зворотному викликом конструкторів. Це спрощує (досить оголосити змінну) і робить більш надійним звільнення ресурсів (пам'ять, файли, семафори і т. п.), а також дозволяє гарантовано виконувати переходи станів програми, не обов'язково пов'язані зі звільненням ресурсів (наприклад, запис в журнал).
  • Функції для користувачів-оператори дозволяють коротко і ємко записувати вирази над користувацькими типами у природному алгебраїчній формі.
  • Мова підтримує поняття фізичної (const) і логічної (mutable) константності. Це робить програму надійніше, тому що дозволяє компілятору, наприклад, діагностувати помилкові спроби зміни значення змінної. Оголошення константності дає програмісту, що читає текст програми додаткове уявлення про правильне використання класів і функцій, а також може бути підказкою для оптимізації. Перевантаження функцій-членів за ознакою константності дозволяє визначати зсередини об'єкта мету виклику методу (константний для читання, неконстантний для зміни). Оголошення mutable дозволяє зберігати логічну константность при використанні кешей і ледачих обчислень.
  • Використовуючи шаблони, можливо створювати узагальнені контейнери і алгоритми для різних типів даних, а також спеціалізувати і обчислювати на етапі компіляції.
  • Можливість імітації розширення мови для підтримки парадигм, які не підтримуються компіляторами безпосередньо. Наприклад, бібліотека Boost.Bind дозволяє пов'язувати аргументи функцій.
  • Можливість створення вбудованих предметно-орієнтованих мов програмування. Такий підхід використовує, наприклад бібліотека Boost.Spirit, що дозволяє задавати EBNF -граматику парсеров прямо в коді C + +.
  • Використовуючи шаблони і множинне спадкування можна імітувати класи-домішки і комбінаторну параметризацію бібліотек. Такий підхід застосовано в бібліотеці Loki, клас SmartPtr якої дозволяє, керуючи лише кількома параметрами часу компіляції, згенерувати близько 300 видів "розумних покажчиків" для управління ресурсами.
  • Кросплатформеність : стандарт мови накладає мінімальні вимоги на ЕОМ для запуску скомпільованих програм. Для визначення реальних властивостей системи виконання в стандартній бібліотеці присутні відповідні можливості (наприклад, std::numeric_limits ). Доступні компілятори для великої кількості платформ, на мові C + + розробляють програми для самих різних платформ і систем.
  • Ефективність. Мова спроектований так, щоб дати програмістові максимальний контроль над усіма аспектами структури та порядку виконання програми. Жодна з мовних можливостей, що призводить до додаткових накладних витрат, не є обов'язковою для використання - при необхідності мова дозволяє забезпечити максимальну ефективність програми.
  • Є можливість роботи на низькому рівні з пам'яттю, адресами.
  • Висока сумісність з мовою C, що дозволяє використовувати весь існуючий C-код (код на C може бути з мінімальними переробками скомпільований компілятором C + +; бібліотеки, написані на C, звичайно можуть бути викликані з C + + безпосередньо без будь-яких додаткових витрат, в тому числі і на рівні функцій зворотного виклику, дозволяючи бібліотекам, написаним на C, викликати код, написаний на С + +).

8.2. Критика

Критику мови C + + можна розділити на кілька груп заяв. Критики вважають, що:

  • Синтаксис, успадкований від C, незручний.
  • Мова містить занадто багато можливостей, вони можуть бути небезпечні.
  • Навпаки, мова не містить деяких можливостей.
  • Мові властиві проблеми продуктивності.

8.2.1. Критика синтаксису

  • Операція присвоювання позначається як =, а операція порівняння як ==. Їх легко сплутати, при цьому операція присвоювання повертає значення, тому присвоювання на місці висловлювання є синтаксично коректним, а в конструкціях циклу і розгалуження поява числа на місці логічного значення також є недопустимим, так що помилкова конструкція виявляється синтаксично правильною. Типовий приклад подібної помилки:
     if  (  x  =  0  )  {  оператори  } 
    Тут в умовному операторі помилково написано присвоювання замість порівняння. В результаті, замість того, щоб порівняти поточне значення x з нулем, програма присвоїть x нульове значення, а потім інтерпретує його як значення умови в операторі if. Так як нуль відповідає логічному значенню "брехня", блок операторів в умовній конструкції не виконається ніколи. Помилки такого роду важко виявляти, але в багатьох сучасних компіляторах пропонується діагностика деяких подібних конструкцій.
  • Операції присвоювання ( =), інкрементаціі ( ++), декрементаціі ( --) та інші повертають значення. У поєднанні з великою кількістю операцій це дозволяє, хоча і не зобов'язує, створювати мають важко вирази. Наявність цих операцій в C було викликано бажанням отримати інструмент ручної оптимізації коду [джерело не вказано 454 дні], але в даний час оптимізують компілятори зазвичай генерують оптимальний код і на традиційних висловах. З іншого боку, один з основних принципів мов C і C + + - дозволяти програмістові писати в будь-якому стилі, а не нав'язувати "хороший" стиль.
  • Деякі перетворення типів неінтуітівни [джерело не вказано 454 дні]. Зокрема, операція над беззнакові і знаковим числами видає беззнакових результат.
  • Багато конструкцій С + + дозволяють робити те ж саме, що і конструкції C, також присутні в С + +. Це іноді збиває з пантелику новачків. Наприклад, приведення типів за допомогою dynamic_cast дозволяє привести покажчик або посилання строго в межах ієрархії класів. Це робить код більш надійним, декларативним і дозволяє знаходити приведення в межах ієрархії за допомогою інструментів типу grep. Однак внаслідок вимоги високого ступеня сумісності з C старе приведення типів все ще підтримується.

8.2.2. Критика наявності можливостей

  • C + + дозволяє пропускати break в гілці оператора switch з метою послідовного виконання кількох гілок. Такий же підхід прийнятий в мові Java [12]. Є думка, що це ускладнює розуміння коду. Наприклад, у мові C # необхідно завжди писати або break, або використовувати goto case N для явної вказівки порядку виконання [13].
  • Макроси ( #define) є могутнім, але небезпечним засобом. Вони збережені в C + + незважаючи на те, що необхідність в них, завдяки шаблонам і вбудованим функціям, не так вже й велика. У успадкованих стандартних C-бібліотеках багато потенційно небезпечних макросів [14].

8.2.3. Критика відсутності можливостей

  • Препроцесор, успадкований від C, дуже примітивний. Це призводить з одного боку до того, що з його допомогою не можна (або важко) здійснювати деякі завдання метапрограмування, а з іншого, внаслідок своєї примітивності, він часто приводить до помилок і вимагає багато дій з обходу потенційних проблем. Деякі мови програмування (наприклад, Scheme і Nemerle) мають набагато могутніші і безпечніші системи метапрограмування (також звані макросами, але мало нагадують макроси C / C + +).
  • Погана підтримка модульності (по суті, в класичному C модульність на рівні мови відсутня, її забезпечення перекладено на компонувальник). Підключення інтерфейсу зовнішнього модуля через препроцесорну вставку заголовного файлу ( #include) серйозно уповільнює компіляцію при підключенні великої кількості модулів (бо результуючий файл, який обробляється компілятором, виявляється дуже великий). Ця схема без змін скопійована в C + +. Для усунення цього недоліку багато компілятори реалізують механізм прекомпіляції заголовних файлів.
  • Метапрограмування на основі шаблонів C + + складно і при цьому обмежене в можливостях. Воно полягає в реалізації засобами шаблонів C + + інтерпретатора примітивного функціональної мови програмування, що виконується під час компіляції. Сама по собі ця можливість вельми приваблива, але такий код вельми важко сприймати і налагоджувати. Менш поширені [15] мови Lisp / Scheme, Nemerle мають більш потужні і водночас більш прості для сприйняття підсистеми метапрограмування. Крім того, в мові D реалізована порівнянна по потужності, але значно простіша в застосуванні підсистема шаблонного метапрограмування.
  • Явна підтримка функціонального програмування присутня тільки в майбутньому стандарті C + +0 x. Ця прогалина усувається різними бібліотеками ( Loki, Boost), які використовують засоби метапрограмування для розширення мови функціональними конструкціями (наприклад, підтримкою лямбда / анонімних методів), але якість подібних рішень значно поступається якості вбудованих у функціональні мови рішень. Такі можливості функціональних мов, як зіставлення зі зразком, взагалі вкрай складно емулювати засобами метапрограмування.
  • Деякі вважають недоліком мови C + + відсутність вбудованої системи збірки сміття. З іншого боку, кошти C + + дозволяють реалізувати збірку сміття на рівні бібліотеки [16]. Противники збірки сміття вважають, що RAII є більш гідною альтернативою. С + + дозволяє користувачеві самому вибирати стратегію управління ресурсами.

8.2.4. Критика продуктивності

  • Іноді шаблони приводять до породження коду дуже великого обсягу [17]. Для зниження розміру машинного коду можна спеціальним чином готувати вихідний код [18]. Іншим рішенням є стандартизована ще в 1998 році можливість експорту шаблонів. Деякі автори вважають, що її важко реалізувати і тому вона доступна не у всіх компіляторах [19] [20] [21]. "Роздування" машинного коду внаслідок використання шаблонів часто перебільшується, і сучасні компілятори у багатьох випадках успішно усувають це явище [22].

8.3. Контраргументи

Прихильники мови вважають, що при оцінці критичних висловлювань з приводу С + + необхідно враховувати наступне:

  • Висока сумісність з C є однією з принципових рис мови, в тому числі, підтримується майже весь синтаксис C.
  • В С + + можна не використовувати певні мовні засоби відповідно до особистих переваг і рівнем знань програміста. Це відноситься і до макросів і до шаблонів.
  • В силу найширшого охоплення різних парадигм програмування, С + + порівнюється з абсолютно різними мовами, і в кожній мові можна знайти деяку можливість, відсутню в С + +. При цьому в С + + є можливості, відсутні в мовах, з якими проводиться порівняння. Наприклад, виклик деструктора після закінчення часу життя об'єкта.

9. Порівняння C + + з мовою Java

Див також: (Англ.) Comparison of Java and C + +

Метою створення C + + було розширення можливостей C, найбільш поширеного мови системного програмування. Орієнтований на ту ж саму область застосування, C + + успадкував безліч не найкращих, з теоретичної точки зору, особливостей C [ яких? ] . Перераховані вище принципи, яких дотримувався автор мови, визначили багато недоліків C + + [джерело не вказано 454 дні].

В області прикладного програмування альтернативою C + + став його мова-нащадок, Java. Незважаючи на спадкоємність по відношенню до C + +, Java будувалася на принципово іншій основі, її розробники не були пов'язані вимог сумісності з мовою-предком і забезпечення максимально досяжної ефективності, завдяки чому вони змогли кардинально переробити мову, відмовитися від безлічі синтаксичних засобів, щоб домогтися ідеологічної цілісності мови. Пізніше компанія Microsoft запропонувала мову C #, що представляє собою ще одну переробку C + + в тому ж напрямку, що і Java. Надалі з'явилася мова Nemerle, в якому до засобів C # додані кошти функціонального програмування. Ще пізніше з'явилася спроба об'єднання ефективності C + + з безпекою і швидкістю розробки Java і C # - був запропонований мову D, який поки не отримав широкого визнання.

Java і C + + можна розглядати як дві мови-нащадка C, розроблених з різних міркувань і пішли, внаслідок цього, за різними шляхами. У зв'язку з цим представляє інтерес порівняння даних мов (все, сказане нижче про Java, можна з рівним успіхом віднести до мов C # і Nemerle, оскільки в розглянутих деталях ці мови відрізняються лише зовні).

Синтаксис
C + + зберігає сумісність з C, наскільки це можливо. Java зберігає зовнішню подібність C і C + +, але насправді сильно відрізняється від них - з мови видалено велике число синтаксичних засобів, оголошених необов'язковими. В результаті програми на Java бувають більш громіздкі в порівнянні з їх аналогами на С + +. З іншого боку, Java простіше, що полегшує як вивчення мови, так і створення трансляторів для нього.
Виконання програми
Java-код компілюється в проміжний код, який надалі інтерпретується або компілюється, тоді як C + + з самого початку орієнтований на компіляцію в машинний код заданої платформи (хоча, теоретично, ніщо не заважає створювати для C + + транслятори в проміжний код). Це вже визначає різницю в сферах застосування мов: Java навряд чи може бути використана при написанні таких специфічних програм, як драйвери пристроїв або низькорівневі системні утиліти. Механізм виконання Java робить програми, навіть відкомпілювалися (в байт-код) повністю переносяться. Стандартне оточення і середовище виконання дозволяють виконувати програми на Java на будь-якій апаратній платформі і в будь-якій ОС, без будь-яких змін, зусилля по портированию програм мінімальні (при дотриманні рекомендацій по створенню переносних програм - і зовсім нульові). Ціною переносимості стає втрата ефективності - робота середовища виконання призводить до додаткових накладних витрат.
Управління ресурсами
C + + дозволяє використовувати принцип "захоплення ресурсів шляхом ініціалізації" (RAII), при якому ресурси асоційовані з об'єктом і автоматично звільняються при руйнуванні об'єкта (наприклад, std::vector і std::ifstream). Також можливий підхід, коли програміст, виділяючи ресурси (пам'ять під об'єкти, відкриті файли і т. п.), зобов'язаний явно подбати про своєчасне їх звільнення. Java працює в середовищі з збіркою сміття, яка автоматично відстежує припинення використання об'єктів і звільняє займану ними пам'ять, якщо в цьому є необхідність, в певний невизначений момент часу. Ручне управління переважно в системному програмуванні, де потрібен повний контроль над ресурсами, RAII і збірка сміття зручніше в прикладному програмуванні, оскільки в значній мірі звільняють програміста від необхідності відстежувати момент припинення використання ресурсів. Збирач сміття Java вимагає системних ресурсів, що знижує ефективність виконання програм, позбавляє програми на Java детермінованості виконання і здатний стежити тільки за пам'яттю. Файли, канали, сокети, об'єкти графічного інтерфейсу програміст на Java завжди звільняє явно.
Стандартизація оточення
В Java є чітко визначені стандарти на введення-виведення, графіку, геометрію, діалог, доступ до баз даних та іншим типовим додатків. C + + в цьому відношенні набагато вільніший. Стандарти на графіку, доступ до баз даних і т. д. є недоліком, якщо програміст хоче визначити свій власний стандарт.
Покажчики
C + + зберігає можливість роботи з низькорівневими покажчиками. У Java покажчиків немає. Використання покажчиків часто є причиною труднообнаружіваемих помилок, але необхідно для низькорівневого програмування. В принципі, C + + володіє набором засобів (конструктори і деструктори, стандартні шаблони, посилання), що дозволяють майже повністю виключити виділення і звільнення пам'яті вручну і небезпечні операції з вказівниками. Проте таке виключення вимагає певної культури програмування, тоді як у мові Java воно реалізується автоматично.
Парадигма програмування
На відміну від С + +, Java є чисто об'єктно-орієнтованою мовою, без можливості процедурного програмування. Для оголошення вільних функцій або глобальних змінних в Java необхідно створювати фіктивні класи, що містять тільки static члени [23]. Для завдання головної функції навіть самої простої програми на Java необхідно помістити її в клас [24].
Динамічна інформація про типи
в C + + RTTI обмежена можливістю порівнювати типи об'єктів між собою і з буквальними значеннями типів. В системі Java доступна детальніша інформація про типи. Цю можливість можна було б реалізувати в C + +, маючи повну інформацію про типи під час компіляції CTTI.
Препроцесор
C + + використовує препроцесор для включення визначень функцій і класів, для підключення бібліотек, повністю виконаних у вихідному коді, а також дозволяє здійснювати метапрограмування з використанням препроцесора, яке, зокрема, вирішує складні проблеми високорівневого дублювання коду [25]. Є думка, що цей механізм небезпечний, тому що імена макросів препроцесора глобальні, а самі макроси майже ніяк не пов'язані з конструкціями мови. Це може призводити до складних конфліктів імен. З іншої точки зору, C + + надає достатньо засобів (константи, шаблони, вбудовані функції) для того, щоб практично повністю виключити використання препроцесора. Java виключила препроцесор повністю, позбувшись разом від всіх проблем з його використанням, втративши при цьому можливості метапрограмування препроцесора і текстових замін в коді засобами мови.

Відмінності мов призводять до запеклих суперечок між прихильниками двох мов про те, яка мова краще. Спори ці багато в чому безпредметні, оскільки прихильники Java вважають відмінності говорять на користь Java, а прихильники C + + вважають зворотне. C + +, в свою чергу, розвивався, і ряд його недоліків усунута в останніх версіях стандарту (наприклад, з'явився механізм часткової специфікації шаблонів).

Далеко не всі програмісти є прихильниками однієї з мов [джерело не вказано 454 дні]. На думку більшості [джерело не вказано 454 дні] програмістів, Java і C + + не є конкурентами, тому що мають різні областями застосовності. Інші вважають [джерело не вказано 454 дні], що вибір мови для багатьох завдань є питанням особистого смаку.


Примітки

  1. Herbert Schildt C + + The Complete Reference Third Edition - Osborne McGraw-Hill. - ISBN 978-0078824760.
  2. 1 2 Б. Страуструп. 2.1. Що таке C + +? / / Мова програмування C + +. Указ. соч - С. 57.
  3. Programming Language Popularity - www.langpop.com/ (2009).
  4. TIOBE Programming Community Index - www.tiobe.com / index.php / content / paperinfo / tpci / index.html (2009).
  5. Стенлі Липпман, Pure C + +: Hello, C + + / CLI - msdn.microsoft.com/en-us/magazine/cc163681.aspx (Англ.)
  6. C + + - Standards - www.open-std.org/jtc1/sc22/wg21/docs/standards
  7. 1 2 3 Б. Страуструп. 1.4. Історичні зауваження / / Мова програмування C + +. Указ. соч - С. 46.
  8. Stroustrup, Bjarne C + + Glossary - www.research.att.com/ ~ bs / glossary.html.
  9. Страуструп Б. Дизайн і еволюція C + + = The Design and Evolution of C + + - СПб. : Питер, 2007. - 445 с. - ISBN 5-469-01217-4.
  10. ISO / IEC 14882:1998, розділ 6.4, пункт 4: "The Value Of A Condition That IS An initialized Declaration In A Statement Other Than A switch Statement IS The Value Of The declared Variable implicitly Converted To bool... The value of a condition that is an expression is the value of the expression, implicitly Converted To bool For Statements Other Than switch; if that conversion is ill-formed, the program is ill-formed ".
  11. STLport: Welcome! - www.stlport.org/
  12. The Java Tutorials: The switch Statement - java.sun.com / docs / books / tutorial / java / nutsandbolts / switch.html
  13. MSDN: The switch statement in C # - msdn.microsoft.com/en-us/library/06tc147t (VS.71). aspx
  14. Страуструп, Б'ярні. Макроси / / Програмування: Принципи та практика використання C + + = Programming: Principles and Practice Using C + + - М .: ТОВ "І. Д. Вільямс", 2001. - С. 1065, 1066, 1133. - 1248 с. - ISBN 978-5-8459-1621-1.
  15. TIOBE Programming Community Index for January 2010 - www.tiobe.com / index.php / content / paperinfo / tpci / index.html
  16. Boehm-Demers-Weiser garbage collector for C and C + + - www.hpl.hp.com/personal/Hans_Boehm/gc/
  17. Dave Gottner. Templates Without Code Bloat - www.ddj.com/cpp/184403053 / / Dr.Dobb's Journal. - Січень 1995.
  18. Adrian Stone. Minimizing Code Bloat: Redundant Template Instantiation - gameangst.com /? p = 246. Game Angst (22 вересня 2009).
  19. Herb Sutter. C + + Conformance Roundup - www.ddj.com/cpp/184401381 / / Dr.Dobb's Journal. - Січень 2001.
  20. Are there any compilers that implement all of this? - www.comeaucomputing.com / csc / faq.html # C8. comp.std.c + + frequently asked questions / The C + + language. Comeau Computing (англ.) (10 грудня 2008).
  21. vanDooren. C + + keyword of the day: export - msmvps.com/blogs/vandooren/archive/2008/09/24/c-keyword-of-the-day-export.aspx. Blogs @ MSMVPs (24 вересня 2008). - "The export keyword is a bit like the Higgs boson of C + +. Theoretically it exists, it is described by the standard, and noone has seen it in the wild. ... There is 1 C + + compiler front-end in the world which actually supports it "
  22. Scott Meyers. Code Bloat due to Templates - groups.google.com / group / comp.lang.c .moderated/browse_thread/thread/2b00649a935997f5/5feec243078c5fd8. comp.lang.c + +. moderated. Usenet (16 травня 2002).
  23. Class Arrays, JavaTM 2 Platform Std. Ed. v1.4.2 - java.sun.com/j2se/1.4.2/docs/api/java/util/Arrays.html
  24. The Java Tutorials. A Closer Look at the "Hello World!" Application - java.sun.com / docs / books / tutorial / getStarted / application / index.html
  25. From "C + + Template Metaprogramming," by David Abrahams and Aleksey Gurtovoy. Copyright (c) 2005 by Pearson - www.boostpro.com / tmpbook / preprocessor.html

Література

  • Страуструп Б. Програмування: принципи і практика використання C + +, виправлене видання = Programming: Principles and Practice Using C + + - М .: "Вільямс", 2011. - С. 1248. - ISBN 978-5-8459-1705-8.
  • Айвор Хортон Visual C + + 2010: повний курс = Ivor Horton's Beginning Visual C + + 2010 - М .: "Діалектика", 2010. - С. 1216. - ISBN 978-5-8459-1698-3.
  • Б. Страуструп. Мова програмування C + + = The C + + Programming Language / Пер. з англ - 3-е изд. - СПб. ; М .: Невський діалект - Біном, 1999. - 991 с. - 3000 екз . - ISBN 5-7940-0031-7 (Невський діалект), ISBN 5-7989-0127-0 (Біном), ISBN 0-201-88954-4 (англ.).
  • Страуструп Б. Мова програмування C + +. Спеціальне видання = The C + + programming language. Special edition - М .: Біном-Пресс, 2007. - 1104 с. - ISBN 5-7989-0223-4.
  • Герберт Шилдт Повний довідник по C + +, 4-е видання = C + +: The Complete Reference, 4th Edition - М .: "Вільямс", 2011. - С. 800. - ISBN 978-5-8459-0489-8.
  • Девід Р. Мюссер, Жілмер Дж. Дердж, Атул Сейн C + + і STL: посібник, 2-е видання (серія C + + in Depth) = STL Tutorial and Reference Guide: C + + Programming with the Standard Template Library, 2nd edition, (C + + in Depth Series) - М .: "Вільямс", 2010. - С. 432. - ISBN 978-5-8459-1665-5.
  • Джесс Ліберті, Девід Хорват. Освой самостійно C + + за 24 години = Sams Teach Yourself C + + in 24 Hours, Complete Starter Kit - 4-е изд. - М .: Вільямс, 2007. - 448 с. - ISBN 0-672-32681-7.
  • Стефенс Д. Р. C + +. Збірник рецептів - КУДИЦ-ПРЕСС, 2007. - 624 с. - ISBN 5-91136-030-6.

Цей текст може містити помилки.

Схожі роботи | скачати
© Усі права захищені
написати до нас
Рейтинг@Mail.ru