Рубрики

const_cast в C ++ | Операторы типа Cast

C ++ поддерживает следующие 4 типа операторов приведения:

1. const_cast
2. static_cast
3. dynamic_cast
4. reinterpret_cast

1. const_cast
const_cast используется для отбрасывания константности переменных. Ниже приведены некоторые интересные факты о const_cast.

1) const_cast может использоваться для изменения неконстантных членов класса внутри константной функции-члена. Рассмотрим следующий фрагмент кода. Внутри функции-члена const fun () «this» обрабатывается компилятором как «const student * const this», то есть «this» является постоянным указателем на постоянный объект, поэтому компилятор не позволяет изменять элементы данных с помощью указатель «этот». const_cast меняет тип указателя this на «student * const this».

#include <iostream>

using namespace std;

  

class student

{

private:

    int roll;

public:

    // конструктор

    student(int r):roll(r) {}

  

    // const-функция, которая меняет roll с помощью const_cast

    void fun() const

    {

        ( const_cast <student*> (this) )->roll = 5;

    }

  

    int getRoll()  { return roll; }

};

  

int main(void)

{

    student s(3);

    cout << "Old roll number: " << s.getRoll() << endl;

  

    s.fun();

  

    cout << "New roll number: " << s.getRoll() << endl;

  

    return 0;

}

Выход:

Old roll number: 3
New roll number: 5

2) const_cast может использоваться для передачи данных const в функцию, которая не получает const. Например, в следующей программе fun () получает нормальный указатель, но указатель на const можно передать с помощью const_cast.

#include <iostream>

using namespace std;

  

int fun(int* ptr)

{

    return (*ptr + 10);

}

  

int main(void)

{

    const int val = 10;

    const int *ptr = &val;

    int *ptr1 = const_cast <int *>(ptr);

    cout << fun(ptr1);

    return 0;

}

Выход:

20

3) Не определено поведение для изменения значения, которое первоначально объявлено как const. Рассмотрим следующую программу. Вывод программы не определен. Переменная 'val' является константной переменной, и вызов 'fun (ptr1)' пытается изменить 'val' с помощью const_cast.

#include <iostream>

using namespace std;

  

int fun(int* ptr)

{

    *ptr = *ptr + 10;

    return (*ptr);

}

  

int main(void)

{

    const int val = 10;

    const int *ptr = &val;

    int *ptr1 = const_cast <int *>(ptr);

    fun(ptr1);

    cout << val;

    return 0;

}

Выход:

 Undefined Behavior 

Можно изменить значение, которое изначально не объявлено как const. Например, в приведенной выше программе, если мы удалим const из объявления val, программа выдаст 20 в качестве вывода.

#include <iostream>

using namespace std;

  

int fun(int* ptr)

{

    *ptr = *ptr + 10;

    return (*ptr);

}

  

int main(void)

{

    int val = 10;

    const int *ptr = &val;

    int *ptr1 = const_cast <int *>(ptr);

    fun(ptr1);

    cout << val;

    return 0;

}

4) const_cast считается более безопасным, чем простое приведение типов. Это безопаснее в том смысле, что приведение не произойдет, если тип приведения не совпадает с исходным объектом. Например, следующая программа завершается неудачно при компиляции, поскольку тип int * приводится к типу char *

#include <iostream>

using namespace std;

  

int main(void)

{

    int a1 = 40;

    const int* b1 = &a1;

    char* c1 = const_cast <char *> (b1); // ошибка компилятора

    *c1 = 'A';

    return 0;

}

выход:

prog.cpp: In function ‘int main()’:
prog.cpp:8: error: invalid const_cast from type 'const int*' to type 'char*'

5) const_cast также может быть использован для отбрасывания изменчивого атрибута. Например, в следующей программе typeid для b1 — это PVKi (указатель на переменное и постоянное целое число), а для typeid для c1 — это Pi (указатель на целое число)

#include <iostream>
#include <typeinfo>

using namespace std;

  

int main(void)

{

    int a1 = 40;

    const volatile int* b1 = &a1;

    cout << "typeid of b1 " << typeid(b1).name() << '\n';

    int* c1 = const_cast <int *> (b1);

    cout << "typeid of c1 " << typeid(c1).name() << '\n';

    return 0;

}

Выход:

typeid of b1 PVKi
typeid of c1 Pi

Упражнение
Прогнозировать выход следующих программ. Если есть ошибки компиляции, то исправьте их.

Вопрос 1

#include <iostream>

using namespace std;

  

int main(void)

{

    int a1 = 40;

    const int* b1 = &a1;

    char* c1 = (char *)(b1);

    *c1 = 'A';

    return 0;

}

вопрос 2

#include <iostream>

using namespace std;

  

class student

{

private:

    const int roll;

public:

    // конструктор

    student(int r):roll(r) {}

  

    // const-функция, которая меняет roll с помощью const_cast

    void fun() const

    {

        ( const_cast <student*> (this) )->roll = 5;

    }

  

    int getRoll()  { return roll; }

};

  

int main(void)

{

    student s(3);

    cout << "Old roll number: " << s.getRoll() << endl;

  

    s.fun();

  

    cout << "New roll number: " << s.getRoll() << endl;

  

    return 0;

}

Аашиш Барнвал . Пожалуйста, напишите комментарии, если вы обнаружите что-то неправильное, или вы хотите поделиться дополнительной информацией по обсуждаемой выше теме.

Рекомендуемые посты:

const_cast в C ++ | Операторы типа Cast

0.00 (0%) 0 votes