Нет. C-бросок может делать эквивалент const_cast
, static_cast
, reinterpret_cast
или их комбинации. В случае, если этого было недостаточно, он также может сделать хотя бы один незначительный трюк, который нет комбинация более новых приведений может сделать вообще!
Вы можете использовать const_cast
с определенными результатами, если исходная переменная определена без const
, но у вас есть только const
указатель или ссылка на этот объект. OTOH, если вы считаете, что у вас есть веские основания для использования const_cast
, есть вероятность, что вы действительно должны искать mutable
вместо этого.
Редактировать: Полагаю, я должен был сказать это сразу, но приведение в стиле C может преобразовать в недоступный базовый класс. Например, рассмотрим что-то вроде:
[Редактировать: я обновляю код до того, что компилируется и (обычно) демонстрирует проблему. ]
#include <iostream>
class base1 {
public:
virtual void print() { std::cout << "base 1\n"; }
};
class base2 {
public:
virtual void print() { std::cout << "base 2\n"; }
};
class derived : base1, base2 {}; // note: private inheritance
int main() {
derived *d = new derived;
base1 *b1 = (base1 *)d; // allowed
b1->print(); // prints "base 1"
base2 *b2 = (base2 *)d; // also allowed
b2->print(); // prints "base 2"
// base1 *bb1 = static_cast<base *>(d); // not allowed: base is inaccessible
// Using `reinterpret_cast` allows the code to compile.
// Unfortunately the result is different, and normally won't work.
base1 *bb2 = reinterpret_cast<base1 *>(d);
bb2->print(); // may cause nasal demons.
base2 *bb3 = reinterpret_cast<base2 *>(d);
bb3->print(); // likewise
return 0;
}
Код, использующий reinterpret_cast
s, скомпилируется, но попытка использовать результат (по крайней мере, один из двух) вызовет серьезную проблему. reinterpret_cast
берет адрес base производного объекта и пытается обработать его, как если бы это был указанный тип базового объекта - и поскольку (не более) один базовый объект может фактически существовать по этому адресу Попытка относиться к нему как к другому может / вызовет серьезные проблемы. Изменить: В этом случае классы, по сути, идентичны, за исключением того, что они печатают, поэтому, хотя все, что может может произойти, с большинством компиляторов, оба из последних двух будут печатать "базу 1". Reinterpret_cast берет то, что происходит по этому адресу, и пытается использовать его в качестве указанного типа. В этом случае я (пытался) сделать что-то безопасное, но заметное. В реальном коде результат, вероятно, не будет таким красивым.
Приведение в стиле C будет работать как static_cast, если бы код использовал публичное наследование вместо private - т.е. он знает, где в производном классе «живет» каждый объект базового класса, и корректирует результат, поэтому каждый результирующий указатель будет работать, потому что он был настроен так, чтобы указывать в нужном месте.