Почему это не работает без static_cast? - PullRequest
2 голосов
/ 20 марта 2010

Компиляция f работает, но компиляция g завершается с ошибкой.

Почему это происходит?

class A {
public:
  A() {}
};

class B : public A {
public:
  B() {}
};

void f() {
  A* a = new A();
  B* b = static_cast<B*>(a);
}

void g() {
  A* a = new A();
  B* b = a;
}

Ответы [ 5 ]

4 голосов
/ 20 марта 2010

A static_cast вызывает преобразование, которое потенциально небезопасно.

B* b = static_cast<B*>(a);

Это было бы допустимо, если бы a указывал на объект A, который фактически являлся подобъектом базового класса объекта B, однако это не так. Приведение заставляет преобразование.

B* b = a;

Здесь нет приведения, и (правильно) не допускается неявное преобразование из указателя базового класса в указатель производного класса. Указатель на производный класс всегда можно преобразовать в указатель на базовый класс, поскольку объект производного класса всегда содержит подобъект базового класса, но не каждый экземпляр базового класса является подобъектом определенного типа производного класса.

3 голосов
/ 20 марта 2010

Ну да. Выполнение:

B* b = new A();

Небезопасно. Вы получите указатель B на объект A; Вы никогда не строите часть B объекта; ваш объект "нарезан".

С другой стороны ...

A* a = new B();

... было бы хорошо.

1 голос
/ 20 марта 2010

Да, выдает ошибку, если вы хотите назначить базовый класс типу указателя на производный класс. Нет, это не выдаст ошибку, если вы явно приведете тип указателя, потому что в C ++ вам разрешено стрелять себе в ногу, если вы того пожелаете.

Что именно вас озадачивает или чего вы ожидаете достичь с помощью своего кода?

1 голос
/ 20 марта 2010

Вы пытаетесь преобразовать указатель из A * в B *. Я не уверен, что вы пытаетесь достичь. Но поскольку B * является производным от A *, а не наоборот, это недопустимо. Может быть, вы хотите сделать что-то вроде этого:

int main()
{
///The above code compiles while if I replace above two line in main with below assignment it gives error.
     A *a=new A();
    A * b=new B();

}
0 голосов
/ 20 марта 2010

Базовый класс не может быть неявно преобразован в производный класс. Просто подумай об этом

class A {
  public: int x;
};
class B : public A {
  public: int y;
};
B* b = new A; // assume it works, so 4 bytes is allocated and initialized.
b->y;         // bam! accessing unallocated  region.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...