Почему C ++ позволяет преобразовывать указатель на базовый объект в указатель производного класса

Возможный дубликат:
Даункастинг с использованием Static_cast в C ++

Меня очень смущает, когда нам нужно преобразовать указатель на базовый объект в указатель производного класса?
Может ли кто-нибудь сделать мне одолжение, чтобы привести пример?

0

Решение

Какого рода преобразование ты о чем?

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

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

Необходимость объясняется тем фактом, что без приведения вы не сможете вызывать какой-либо метод производного класса, даже если вы уверены, что указатель на базовый содержит производный (но компилятор не может его проверить ).

1

Другие решения

КОГДА

так вот пример:

скажем, у вас есть фабрика (фабрика животных), которую вы можете отправить ей строку или перечисление того, какой тип объекта вы хотите …

«Эй, Фабрика животных, дай мне собаку»

Есть два способа написать свой завод …

Вы можете написать функцию для каждого животного следующим образом (хорошие программисты этого не делают):

  • Dog * GetDog ();
  • Cat * GetCat ();
  • Так далее

или вы могли бы написать фабрику с одной функцией, например, так (пока не думайте об обобщениях):

  • Animal * GetAnimal (string animalType);

Вы знаете, что на самом деле Animal — это собака или кошка, так что вы можете настроить ее так, как вам нужно. КОГДА вам нужно получить доступ к членам Dog или Cat …

Мое любимое занятие в C ++ — временное приведение к чему-либо
(извините мой C ++ его ржавый)

Animal* myAnimal = Factory.GetAnimal("Dog");
int barkVolume = ((Dog*)myAnimal).BarkVolume;
1

Представьте, что у вас есть базовый класс Animal и два производных класса, Cat а также Dog,

// Assume methods are public.
class Animal { virtual void Attack(); }
class Dog : public Animal { void Meow(); }
class Cat : public Animal { void Bark(); }

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

Animal* myCat = new Cat;
Animal* myDog = newDog;
std::vector<Animal*> myAnimals;
myAnimals.push_back(myCat);
myAnimals.push_back(myDog);

Это полезно, так как мы можем вызывать базовые функции-члены всех видов животных, независимо от их производных типов классов.

// Call Attack() on every cat and dog.
for_each(myAnimals.begin(), myAnimals.end(), [](auto& e) { e->Attack(); });

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

Cat* realCat = dynamic_cast<Cat*> myAnimals[0]; // Success. Pointer is valid.
Cat* fakeCat = dynamic_cast<Cat*> myAnimals[1]; // Failure, it's not a cat. NULL.

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

realCat->Meow(); // Valid.
myCat->Meow(); // Animal*, there is not Meow() method.
1

Это необходимо сделать для доступа к членам производного класса, которых нет в базовом классе. С хорошими практиками программирования и обобщениями, вы все равно не должны указывать в качестве базового класса указатели.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector