Короткий FAQ по C ++
[Всі зареєстровані торгові марки, які згадуються в даному документі, належать їхнім відповідним власникам.]
[8.2] Що відбувається в результаті присвоювання посиланням?
[8.3] Що відбувається, коли я повертаю з функції посилання?
[8.4] Як можна перевстановити посилання, щоб вона посилалася на інший об'єкт?
[8.5] В яких випадках мені варто використовувати посилання, і в яких - покажчики?
РОЗДІЛ [9]: Вбудовані (inline) функції
[9.1] Що таке вбудована функція?
[9.2] Як вбудовані функції можуть впливати на співвідношення безпеки і швидкості?
[9.3] Навіщо мені використовувати вбудовані функції? Чому не використовувати просто #define макроси?
[9.4] Що зробити, щоб визначити функцію - не член класу як вбудовану?
[9.5] Як зробити вбудованої функцію - член класу?
[9.6] Чи є інший спосіб визначити вбудовану функцію - член класу?
[9.7] Чи обов'язково вбудовані функції приведуть до збільшення продуктивності?
РОЗДІЛ [10]: Конструктори
[10.1] Що таке конструктори?
[10.3] Як з одного конструктора викликати інший конструктор для ініціалізації цього об'єкта?
[10.4] Чи завжди конструктор за замовчуванням для Fred виглядає як Fred :: Fred ()?
[10.5] Який конструктор буде викликаний, якщо я створюю масив об'єктів типу Fred?
[10.6] Чи повинні мої конструктори використовувати "списки ініціалізації" або "присвоювання значень"?
[10.7] Чи можна користуватися покажчиком this в конструкторі?
[10.8] Що таке "іменований конструктор" ( "Named Constructor Idiom")?
[10.9] Чому я не можу проинициализировать статичний член класу в списку ініціалізації конструктора?
[10.10] Чому класи зі статичними даними отримують помилки при компонуванні?
[10.11] Що таке помилка в порядку статичної ініціалізації ( "static initialization order fiasco")?
[10.12] Як запобігти помилці в порядку статичної ініціалізації?
[10.13] Як боротися з помилками порядку статичної ініціалізації об'єктів - членів класу?
[10.14] Як мені обробити помилку, яка сталася в конструкторі?
Р АЗДЕЛ [11]: Деструктори
[11.1] Що таке деструктор?
[11.2] У якому порядку викликаються деструктори для локальних об'єктів?
[11.3] У якому порядку викликаються деструктори для масивів об'єктів?
[11.4] Чи можу я перевантажити деструктор для свого класу?
[11.5] Чи можу я явно викликати деструктор для локальної змінної?
[11.6] А що якщо я хочу, щоб локальна змінна "померла" раніше закриває фігурної дужки? Чи можу я при крайній необхідності викликати деструктор для локальної змінної?
[11.7] Добре, я не буду явно викликати деструктор. Але як мені впоратися з цією проблемою?
[11.8] А що робити, якщо я не можу розмістити змінну в окремий блок?
[11.9] А чи можу я явно викликати деструктор для об'єкта, створеного за допомогою new?
[11.10] Що таке "синтаксис розміщення" new ( "placement new") і навіщо він потрібен?
[11.11] Коли я пишу деструктор, чи повинен я явно викликати деструктори для об'єктів-членів мого класу?
[11.12] Коли я пишу деструктор похідного класу, чи потрібно мені явно викликати деструктор предка?
Посилання часто використовуються для передачі параметра за посиланням:
У цьому прикладі i і j - псевдоніми для змінних x і y функції main. Іншими словами, i - це x. Чи не покажчик на x і не копія x. а сам x. Все, що ви робите з i. проробляється з x. і навпаки.
[8.2] Що відбувається в результаті присвоювання посиланням?
[8.3] Що відбувається, коли я повертаю з функції посилання?
В цьому випадку виклик функції може виявитися з лівого боку оператора (операції) присвоювання.
На перший погляд, такий запис може здатися дивною. Наприклад, запис f () = 7 виглядає безглуздою. Однак, якщо a - це об'єкт класу Array. для більшості людей запис a [i] = 7 є осмисленою, хоча a [i] - це всього лише замаскований виклик функції Array :: operator [] (int). яка є оператором звернення за індексом для класу Array.
[8.4] Як можна перевстановити посилання, щоб вона посилалася на інший об'єкт?
Неможливо в принципі.
Неможливо відокремити посилання від її об'єкта.
[8.5] В яких випадках мені варто використовувати посилання, і в яких - покажчики?
Використовуйте посилання, коли можете, а покажчики - коли це необхідно.
Посилання зазвичай краще покажчиків, коли вам непотрібно їх "перенаправляти" [8.4]. Це зазвичай означає, що посилання особливо корисні у відкритій (public) частини класу. Посилання зазвичай з'являються на поверхні об'єкта, а покажчики заховані усередині.
Примітка: програмісти з досвідом роботи на З часто недолюблюють посилання, через те що передача параметра за посиланням явно ніяк не позначав в зухвалій коді. Однак з набуттям деякого досвіду роботи на С ++, вони усвідомлюють, що це одна з форм приховування інформації, яка є швидше перевагою, ніж недоліком. Тобто програмісту слід писати код в термінах задачі, а не комп'ютера (programmers should write code in the language of the problem rather than the language of the machine).
[9.1] Що таке вбудована функція?
Вбудована функція - це функція, код якої прямо вставляється в тому місці, де вона викликана. Як і макроси, визначені через #define. вбудовані функції покращують продуктивність за рахунок вартості виклику і (особливо!) за рахунок можливості додаткової оптимізації ( "процедурна інтеграція").
[9.2] Як вбудовані функції можуть впливати на співвідношення безпеки і швидкості?
У звичайному З ви можете отримати "інкапсульовані структури", поміщаючи в них покажчик на void. і змушуючи його вказувати на справжні дані, тип яких невідомий користувачам структури. Таким чином, користувачі не знають, як інтерпретувати ці дані, а функції доступу перетворять покажчик на void до потрібного прихованого типу. Так досягається певний рівень інкапсуляції.
На жаль, цей метод йде врозріз з безпекою типів, а також вимагає виклику функції для доступу до будь-яких полях структури (якщо ви дозволили б прямий доступ, то його міг би отримати будь-хто, оскільки буде відомо, як інтерпретувати дані, на які вказує void *. Така поведінка з боку користувача призведе до складнощів при подальшій зміні структури підлягають даних).
Вартість виклику функції невелика, але дає деяку надбавку. Класи С ++ дозволяють вбудовування функцій, що дає вам безпеку інкапсуляції разом зі швидкістю прямого доступу. Більш того, типи параметри вбудованих функцій перевіряються компілятором, що є перевагою в порівнянні з (?) Сішнимі #define макросами.
[9.3] Навіщо мені використовувати вбудовані функції? Чому не використовувати просто # defineмакроси?
Оскільки #define макроси небезпечні [9.3], небезпечні [34.1], небезпечні [34.2], небезпечні [34.3].
На відміну від #define макросів, вбудовані (inline) функції несхильний відомим помилкам подвійного обчислення, оскільки кожен аргумент вбудованої функції обчислюється тільки один раз. Іншими словами, виклик вбудованої функції - це те ж саме що і виклик звичайної функції, тільки швидше:
Також, на відміну від макросів, типи аргументів вбудованих функцій перевіряються, і виконуються всі необхідні перетворення.
Макроси шкідливі для здоров'я; не використовуйте їх, якщо це не потрібно