Оператор присвоєння (C++)

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до навігації Перейти до пошуку

В C++, оператор присвоєння, '=', це оператор використовний для присвоєння . Як і більшість інших операторів в С++, він може бути перевантаженим.

Оператор присвоєння копіюванням, часто він називається просто «оператор присвоєння», це особливий випадок оператора, де джерело (права частина) і призначення (ліва частина) одного й того самого класу. Це одна зі спеціальних функцій членів, це означає, що цей оператор автоматично створюється компілятором, якщо його не визначив розробник. Версія створена компілятором виконує почленне копіювання, де кожний з членів копіюється за допомогою свого власного оператора присвоєння (який у свою чергу може бути визначений програмістом або компілятором).

Оператор присвоєння копіюванням відрізняється від конструктора копіювання тим, що він має очистити члени даних об'єкта по лівий бік оператора присвоєння (і також вірно обробити самоприсвоєння), тоді як конструктор копіювання надає значення неініціалізованим членам.[1] For example:

My_Array first; // ініціалізація конструктором по замовченню
My_Array second(first); // ініціалізація конструктором копіювання
My_Array third = first; // також конструктором копіювання
second = third; // присвоєння через оператор присвоєння копіюванням

Перевантаження[ред. | ред. код]

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

  1. Отримати нові ресурси
  2. Вивільнити старі
  3. Присвоїти вказівники нових ресурсів об'єктові
class My_Array 
{

    int * array;
    int count;

public:

    My_Array & operator= (const My_Array & other)
    {
        if (this != &other) // захист проти невірного самоприсвоєння self-assignment
        {
            // 1: зайняти нову ділянку пам'яті та скопіювати елементи
            int * new_array = new int[other.count];
            std::copy(other.array, other.array + other.count, new_array);

            // 2: вивільнити стару пам'ять
            delete [] array;

            // 3: присвоїти нову пам'ять об'єктові
            array = new_array;
            count = other.count;
        }
        // як прийнято, завжди повертаємо *this
        return *this;
    }

    ...

};

Однак, якщо маємо в наявності відмовостійкі функції обміну для всіх членів, і клас забезпечує конструктор копіювання та деструктор (які він імовірно реалізує відповідно до правила трьох), найбезпосередніший спосіб здійснення присвоєння копіюванням такий [2]:

public:

    void swap(My_Array & other) // функція обміну (не має падати!)
    {
        // обмінюємось усіма членами (і базовим підоб'єктом, якщо можливо) з other 
        std::swap(array, other.array);
        std::swap(count, other.count);
    }

    My_Array & operator = (My_Array other) // зауважте: параметр передано за значенням!
    {
        // обмінюємось з other
        swap(other);

        // як прийнято, завжди повертаємо *this
        return *this;

        // other знищується із вивільненням пам'яті
    }

Причиною повернення My_Array& оператором присвоєння замість void є бажання дозволити ланцюгове присвоєння:

array_1 = array_2 = array_3; // array_3 присвоюється array_2 
                             // і тоді array_2 присвоюється array_1

Оператор повертає нестале My_Array&, щоб дозволити таке ланцюгове присвоєння:

(array_1 = array_2) = array_3; // Оператор присвоєння асоціативний справа вліво

Наголосимо, що все це дозволяється з основними типами, як то int.

Див. також[ред. | ред. код]

Примітки[ред. | ред. код]

  1. Страуструп, Б'ярн (2000). The C++ Programming Language (вид. 3). Addison-Wesley. с. 244. ISBN 978-0201700732. {{cite book}}: Проігноровано невідомий параметр |авторлінк= (можливо, |автор-посилання=?) (довідка)
  2. Sutter, H.; Alexandrescu, A. (October 2004), C++ Coding Standards, Addison-Wesley, ISBN 0-321-11358-6