Приведение, особенно приведение в стиле C, говорит компилятору замолчать о многих ошибках и предупреждениях, и вы обещаете, что знаете, что делаете, на свой страх и риск.
Использование указателя, который не указывает на объект этого типа, в большинстве случаев является неопределенным поведением. Неопределенное поведение - только это - нет никаких требований относительно того, что могло бы произойти, таким образом, вы МОЖЕТЕ получить ошибку компилятора или ошибку времени выполнения. Или вам может показаться, что это «работает» (что бы это ни значило), или что-то совершенно неожиданное.
Что касается того, что на самом деле происходит в вашем конкретном случае, функции, скорее всего, используют смежную память, которая не принадлежит *BaseObj
для хранения int
, но впоследствии это не имело значения. Если вы запомнили delete
объект, тем не менее, есть вероятность, что вы столкнетесь с проблемой в этот момент, поскольку перезаписанная память могла использоваться функциями управления кучей памяти.
Обратите внимание, что если Base
имеет хотя бы одну виртуальную функцию (например, деструктор), и если вы используете более безопасный dynamic_cast
вместо наименее безопасного приведения в стиле C, то результатом приведения будет нулевое указатель, поскольку dynamic_cast
проверяет, действительно ли объект относится к этому типу.
class Base {
public:
Base() {
cout << "Base class constructor\n";
}
virtual ~Base() = default;
};
// ...
int main()
{
Base* BaseObj = new Base();
Derived* DerivedObj = dynamic_cast<Derived*>(BaseObj);
if (DerivedObj) {
DerivedObj->SomeMethod();
DerivedObj->SomeMethod_1();
DerivedObj->SomeMethod_2();
} else {
std::cout << "Not a Derived\n";
}
delete BaseObj; // Don't forget to match every "new" with a "delete".
return 0;
}