Как создать родительский класс в качестве дочернего класса
Прошло некоторое время с тех пор, как мне пришлось писать код на С++, и я чувствую себя глупо. Я написал код, похожий на , но не совсем, код ниже:
class Parent
{
...
};
class Child : public Parent
{
...
};
class Factory
{
static Parent GetThing() { Child c; return c; }
};
int main()
{
Parent p = Factory::GetThing();
Child c1 = p; // Fails with "Cannot convert 'Parent' to 'Child'"
Child c2 = (Child)p; // Fails with "Could not find a match for 'TCardReadMessage::TCardReadMessage(TCageMessage)'"
}
Я знаю, что это должно быть просто, но я не уверен, что я делаю неправильно.
Ответы
Ответ 1
A Parent
объект, возвращаемый значением, не может содержать никакой информации Child
. Вы должны работать с указателями, предпочтительно с умными указателями, поэтому вам не нужно очищать себя:
#include <memory>
class Factory
{
// ...
public:
static std::auto_ptr<Parent> GetThing()
{
return std::auto_ptr<Parent>(new Child());
}
};
int main()
{
std::auto_ptr<Parent> p = Factory::GetThing();
if (Child* c = dynamic_cast<Child*>(p.get()))
{
// do Child specific stuff
}
}
Ответ 2
Я думаю, проблема заключается не в том, как вы пытаетесь сделать актерский состав, а в том, почему вы хотите бросить в первую очередь. Код не имеет смысла - даже если он был синтаксически действителен. Вы пытаетесь превратить "плод" в "яблоко" в контексте, где легко доказать, что на самом деле у вас нет яблока. Динамические приемы и аналогичные эффекты полезны только тогда, когда у вас есть указатель на "плод", что у вас есть причины для этого, также является "яблоком".
Ответ 3
Ты не можешь, правда. Ваш factory вернул объект Parent
, который был создан из объекта Child
c
[*]. Детскую часть его уже отрезали, так как она вернулась к функции main
. Нет способа восстановить его.
Возможно, вы хотите использовать указатели?
[*] Кроме того, Child c();
объявляет функцию, она не определяет объект. Но это не ваш реальный код, и я предполагаю, что ваш настоящий класс имеет параметры конструктора.
Ответ 4
Вы не можете отнести объект родительского класса к типу дочернего класса. Объект родительского класса... ну, объект родительского класса. Класс Child расширяет родительский класс, что означает, что объект родительского класса обычно "меньше", чем объект дочернего класса. По этой причине родительский класс (или переосмысление) родительского класса не имеет никакого смысла.
Объясните, что вы пытаетесь сделать. Без объяснения ваш вопрос просто не имеет смысла.
Ответ 5
Вероятно, вы вообще не хотите, чтобы меня бросали. Если у родителя есть абстрактные методы, вы просто вызываете их, и производный класс автоматически обработает их правильно.
Есть моменты, когда вы связываете относительно несвязанные элементы вместе, чтобы сохранить их в коллекции, либо вариантных типах, либо ситуациях, когда другое состояние приводит к несвязанным объектам, которые обрабатываются по-разному, и в тех случаях, которые вы можете захотеть сделать.
Я очень удивлен, кстати, что вы не получили ошибку компилятора в GetThing(), потому что вы объявили c как функцию, чтобы вы не возвращали родителя.
Кроме того, кстати, если вы скопируете по значению, вы будете "нарезать" таким образом:
Child c;
Parent p(c);
Child & c2 = dynamic_cast< Child& >(p); // throws bad_cast
Ответ 6
Обратитесь к фрагменту кода ниже:
Child* c = dynamic_cast<Child*>(parentObject);
где parentObject
имеет тип Parent*
Убедитесь, что "parentObject" на самом деле имеет тип "Child", иначе undefined -behavior.
Обратитесь за Подробнее
Ответ 7
Вы не можете создавать фактические объекты, но вы можете указывать указатели на объекты.
Чтобы наложить указатели, используйте такой код:
Child* c = reinterpret_cast<Child*>(p);