Может ли указатель производного класса быть приведенным по типу к указателю его базового класса? - PullRequest
4 голосов
/ 28 января 2010

Указатель производного класса, возвращаемый функцией new, может быть приведен по типу к указателю его базового класса.

Это правда или ложь?

Я знаю, что dynamic_cast может быть использован для приведения в низ. Вообще, как привести указатель производного класса к указателю его базового класса?

Ответы [ 4 ]

14 голосов
/ 28 января 2010

Да. Преобразование из указателя на производный класс в указатель на базовый класс неявно. Таким образом, следующее прекрасно прекрасно:

struct B { };
struct D : B { };

D* my_d_ptr = new D;
B* my_d_ptr_as_a_b_ptr = my_d_ptr;
4 голосов
/ 28 января 2010

Приведение указателя к производному указателю на базу должно быть неявным. В этом весь смысл полиморфизма: экземпляр производного класса всегда должен безопасно использоваться как экземпляр базового класса. Следовательно, явное приведение не требуется.

3 голосов
/ 28 января 2010

Это верно, если производный класс наследует «публично» и «не виртуально» от базы:

Вы не можете конвертировать Derived* в Base* ни неявно, ни с помощью static_cast / dynamic_cast (C-cast сделает эту работу, но вам следует подумать дважды, прежде чем использовать этот хак!);

class Base { };

class Derived : protected Base { };

int main()
{
   Base* b = new Derived(); // compile error
}

Также не работает, если базовый класс неоднозначен:

class Base { };

class Derived1 : public Base { };
class Derived2 : public Base { };

class MostDerived : public Derived1, Derived2 { };

int main()
{
   Base* b = new MostDerived(); // won't work (but you could hint compiler
                                // which path to use for finding Base
}

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

1 голос
/ 28 января 2010

Ваш вопрос неясен, потому что он смешивает несколько разных вещей.

С одной стороны, указатель на производный класс может быть преобразован в указатель на базовый класс (при условии, что база доступна). Это естественное преобразование, и нет необходимости в том, чтобы кто-то делал это.

С другой стороны, вы упоминаете dynamic_cast и его способность выполнять понижений . Но downcast - это приведение в обратном направлении: от указателя на базовый класс до указателя на производный класс. Даункаст может быть выполнен как dynamic_cast, так и static_cast, в зависимости от того, что вам нужно и какой объем проверки во время выполнения вам требуется.

... И в то же время вы говорите о приведении результата new, который, конечно, может быть только повышен, но не понижен.

Итак, о чем вы спрашиваете? Повышения или понижения?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...