Перетворення типу призначення, використання

Існує два види перетворень: Явна і неявна.

1.Прісвоеніе "більшого типу" значення "меншого типу". Безпечне присвоєння, гарантує збереження значення.

unsigned int UnsignedIntVal;

unsigned char UnsignedCharVal;

2.Прісвоеніе "меншого типу" значення "більшого типу". Потенційно небезпечне привласнення, загрожує втратою інформації.

3.Преобразованіе значення з "меншого типу" в "більший тип". Називається розширенням типу.

4.Преобразованіе значення з "більшого типу" в "менший тип". Називається звуженням типу. Є небезпечним перетворенням.

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

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

  • Присвоєння значення об'єкту перетворює це значення до типу об'єкта.

· Unsigned int MyIntU;

· MyIntU = (unsigned int) 3.14159;

  • Передача значення при виконанні функції перетворює це значення в тип параметра функції. Він стає відомий завдяки прототипу, що викликається.

· Void ff (int); // Прототип функції.

При цьому на стадії трансляції можлива поява попередження про звуження типу.

  • В арифметичному виразі тип результату виразу визначається самим "широким" типом серед усіх утворюють вираз операндів. Цей тип називають результуючим типом виразу. До цього типу перетворюються всі інші операнди.

· Unsigned int MyIntU = 5;

Результуючим типом виразу тут виявляється тип double, представлений в вираженні літералом 3.14159. У процесі обчислення виразу значення змінної MyIntU перетворюється в 5.0, до якого додається 3.14159.

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

· Unsigned int MyIntU = 5;

· MyIntU = MyIntU + 3.14159;

Тут мають місце два послідовних перетворення:

По ходу обчислення виразу значення змінної MyIntU розширюється до double і до розширеної копії значення 5.0 додається 3.14159. Після цього результуюче значення 8.14159, відповідно до першого правилом, звужується до типу unsigned int. В результаті чого виходить значення 8, яке і присвоюється змінної MyIntU.

· Char * p_chVal = 0;

· Const int * pc_iVal = &iVal;

· // ПРАВИЛО 5 виконується.

· // Помилка: pc_iVal - покажчик на константу.

· Const void * pcVal = pc_iVal;

· А тут все добре! Вказівником на константу присвоєно покажчик на константу.

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

char * p_chValName = "Marina";

p_chVal = (char *) p_Val; / * Явна приведення. * /

Механізм неявних перетворень може бути відключений за допомогою явної вказівки в тексті програми необхідного перетворення типів.

Так, модифікація раніше розглянутого прикладу

MyIntU = MyIntU + (int) 3.14159;

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

* Тупо копія. Описати самому ... маячня.

Тут треба зрозуміти все це.

Питання рівносильний «Що таке begin end?»

Класи, що використовують вільну пам'ять: визначення та реалізація, використання примірників класу, що виникають проблеми. Конструктор копіювання і деструктор, перевантаження оператора присвоювання: визначення і використання.

// Не важливо, який тип буде використовувати вільну пам'ять, юзается вона new НЕ

// залежно від того клас це, структура або щось інше.

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

char * buffer = new char [50];

Кажучи коротко, якщо оператор new успішно виділяє пам'ять, він повертає покажчик на початок області цієї пам'яті.

Навіщо необхідно динамічно розподіляти пам'ять з використанням new

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

Конструктор - це метод класу, що виконується автоматично в момент створення об'єкту.

private:
char data;
public:
class (char d): data (d) <>// конструктор (не започатковано)

_class * _example = new _class (tt); // створення в вільної памятіекземпляра класу

cout <<*_example -> data <

private:
char data;
public:
_class (_class _example)

Якщо вашій програмі більше не потрібна виділена пам'ять, вона повинна її звільнити, використовуючи оператор delete. Щоб звільнити пам'ять з використанням оператора delete ви просто вказуєте цього оператора покажчик на дану область пам'яті, як показано нижче:

Деструкція являє собою функцію, яку C ++ автоматично запускає, коли він або ваша програма знищує об'єкт. Деструкція має таке ж ім'я, як і клас об'єкта; однак ви ото випереджує ім'я деструктора символом тильди (

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

private:
char data;
public:
class (char d): data (d) <>

_class (void) <>// вказує деструктор

Оператор присвоювання обов'язково визначається у вигляді функції класу, тому що він нерозривно пов'язаний з об'єктом, що знаходиться зліва від "=". Визначення оператора присвоювання в глобальному вигляді зробило б можливим перевизначення стандартного поведінки оператора "=". приклад:

_class (int i): data (i)<>

_class operator = (const _class right)

if (this == right)

data = right.data; // якщо не дорівнює саме собі, то ...

Типи відносин між класами. Контейнерні класи: визначення, видимість членів класу. Реалізація та виклик конструкторів і деструкторів вкладених класів. Реалізація та використання методів.

// В шпори написано, що всього два типи

У традиційному ООП передбачені три типи відносин між класами:

  • Використання: безпосередня залежність.
    • член класу А відправляє повідомлення об'єкту класу Б
    • член класу А створює або повертає об'єкти класу Б.
  • Включення: іноді називається агрегированием. Реалізує логічні зв'язки типу «є складовою частиною».
    • об'єкт класу А містить внутрішні об'єкти класу Б.
  • Спадкування: реалізує логічні зв'язки типу «є окремим випадком».
    • ///////////////////// пояснюється в 1 квитку.

Контейнер - це спосіб організації зберігання даних. (Стек, масив, зв'язний список ....)

Контейнерні класи - це універсальні шаблонні класи, призначені для зберігання елементів заданого типу в суміжних областях пам'яті. Стандарт C ++ вже включає в себе велику кількість контейнерів, як частина STL (Standard Template Library - Стандартна Бібліотека Шаблонів).

Визначається контейнер, як:

Наприклад: vector example_vector; // створюємо вектор цілих чисел

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

Доступ до компонентів вкладеного класу, які мають атрибут private, можливий тільки з функцій вкладеного класу і з функцій зовнішнього класу, оголошених з специфікатором friend у вкладеному класі.

class cls1 // зовнішній клас

cls2 (int bb). b (bb)<>// конструктор класу cls2

public: // public секція для cls1

class cls3 // вкладений клас

public: // public-секція для класу cls3

cls3 (int cc): c (cc) <>// конструктор класу cls3

cls1 (int aa): a (aa) <>// конструктор класу cls

cls1 :: cls2 bb (456); // помилка cls2 can not access private

cout <

// declared in class 'cls1 :: cls3'

Приклад доступу до private-компонентам вкладеного класу з функцій зовнішнього класу, оголошених з специфікатором friend, наводиться нижче.

void fun (cls1 :: cls2); // функція отримує об'єкт класу cls2

friend void cls1 :: fun (cls1 :: cls2); // ф-ція, дружня класу cls1

cls1. cls2 cc (789);

Зовнішній клас cls1 містить public-функцію fun (cls1 :: cls2 dd), де dd є об'єкт, відповідний класу cls2, вкладеному в клас cls1. У свою чергу в класі cls2 є friend-функція friend void cls1 :: fun (cls1 :: cls2 dd), що забезпечує доступ функції fun класу cls1 до локальної компоненті з класу cls2.

11. Похідні класи: просте спадкування, основні поняття і визначення. Правила визначення похідного класу, типи успадкування, видимість членів класу. Реалізація та використання конструкторів і деструкторів базового і похідних класів. Використання примірників базового і похідних класів. Покажчики на базовий і похідні класи.

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

Дані, заховані в private батьківського класу, не доступні з похідного класу.

A (int a, int b): data (a), vasya (b)

class B: public A

B (int a, int b): aa (a), vasya (b)

a = data; // помилка доступу (data була в private батьківського класу)

a = vasya; // все ок (vasya був в public батьківського класу)

A * aaa = new A; // створення екземпляра класу А (порожній конструктор)

A * aaa_2 = new A (23,42) // створення екземпляра А з заданими параметрами

B * bbb_2 = new B (23, 52) // створення екземпляра B із заданими параметрами (краще використовувати даний варіант)

A * bbb = new B (23, 52) // створення екземпляра B із заданими параметрами (поганий варіант через вивільнення пам'яті надалі)