Вказівник на клас

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

Ми вже з вами вчили вказівники. І що вони є псевдонімами основних змінних. Відповідно, дії з даними вказівниками будуть змінювати значення основної змінно. Звісно ж якщо вказівник не є константним.


Для чого це вам? Як вже було сказано, то основною причиною є ресурсів пристрою завдяки відсутності копіювання В основному при передачі класу як аргумент функції. Також, можна сказати випадково не змінити значення в середині класу можна використовувати константний Але це скоріше принесе вам проблеми, бо тоді доведеться змінювати сам клас.


Створення вказівника на клас ні чим не відрізняється від звичайного вказівника. Відповідно, воно відбувається так:

    
            Ім’я_класу* ім’я_вказівника;
        
    

Або ви можете присвоїти (ініціалізувати) вказівник відразу.

    
            Ім’я_класу* ім’я_вказівника = &ім’я_змінної_типу_клас;
        
    

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

    
            Ім’я_вказівника -> елемент/метод;
        
    

Погляньте на приклад програми:

    
            #include <iostream>

            class MyClass {
            public:
                int age = 4;

                void funInputAge()
                {
                    std::cout << "Input age: ";
                    std::cin >> age;
                }

                void funOutputAge()
                {
                    std::cout << "Age: " << age;
                }
            };


            int main()
            {
                MyClass myClass;

                //створюємо вказівник на клас
                MyClass* ptrMyClass = &myClass;

                std::cout << "Input Age please: ";

                //звертаємося до елементу класу
                std::cin >> ptrMyClass->age;

                //викликаємо метод класу
                ptrMyClass->funOutputAge();
            }
        
    

Звісно ж, ви можете змінювати змінну на, яку вказуватиме вказівник:

    
            #include <iostream>

            class MyClass {
            public:
                int age = 4;

                void funInputAge()
                {
                    std::cout << "Input age: ";
                    std::cin >> age;
                }

                void funOutputAge()
                {
                    std::cout << "Age: " << age;
                }
            };


            int main()
            {
                MyClass myClass_1, myClass_2;
                MyClass* ptrMyClass;

                //ми можемо присвоїти значення з початку на один клас
                ptrMyClass = &myClass_1;

                ptrMyClass->funInputAge();
                ptrMyClass->funOutputAge();

                //після чого можемо переприсвоїти значення на інший клас
                ptrMyClass = &myClass_2;

                ptrMyClass->funOutputAge();
            }
        
    

Зверніть увагу, що з початку ми вказували на першу змінну класу Змінили її значення змінної та вивели його за допомогою методів класу. Далі, ми переприсвоїли значення вказівника на змінну і не змінюючи значення вивели його. Це продемонструвало те, що ми дійсно змінили змінну класу на яку вказували.


Пам’ятайте, якщо ви не хочете змінити дані через вказівник, то вам варто використати константний вказівник.

    
            Ім’я_класу* const ім’я_вказівника = &ім’я_змінної_типу_клас;
        
    

Важлива деталь! В такому випадку ви не зможете викликати не константні методи! Тому, вам доведеться змінити свої методи зробивши їх константними. Мабуть, це все не варте зусиль. Тому, лише для прикладу розглянемо це.

Ось приклад коду:

    
            #include <iostream>

            class MyClass {
            public:
                int age = 4;

                void funInputAge()
                {
                    std::cout << "Input age: ";
                    std::cin >> age;
                }

                //оскільки метод є константним, то ми зможемо викликати
                //його за допомогою константного вказівника
                void funOutputAge() const
                {
                    std::cout << "Age: " << age;
                }
            };

            int main()
            {
                MyClass myClass;

                //створюємо вказівник на клас
                const MyClass* ptrMyClass = &myClass;


                //звертаємося до елементу класу
                //на пряму робити це заборонено, тому отримаємо помилку
                //std::cin >> ptrMyClass->age;

                //маємо право викликати константний метод
                ptrMyClass->funOutputAge();

                //але не маємо права викликати не константний метод
                //ptrMyClass->funInputAge();
            }
        
    

Основна суть створення вказівника на клас це передача його у функцію. Це відбувається аналогічно до вказівників на звичайні аргументи.

        
            #include <iostream>

            class MyClass {
            public:
                int age = 4;

                void funInputAge()
                {
                    std::cout << "Input age: ";
                    std::cin >> age;
                }

                void funOutputAge()
                {
                    std::cout << "Age: " << age;
                }
            };

            //створюємо функцію, яка приймає в якості аргумента вказівник на клас
            void fun(MyClass* ptrMyClass)
            {
                ptrMyClass->funInputAge();
                ptrMyClass->funOutputAge();
            }

            int main()
            {
                MyClass myClass;

                //передаємо у функцію адресу класу
                fun(&myClass);
            }
        
    



Ви повинні увійти, щоб залишати коментарі.


Коментарі: