#c #class #inheritance
#c #класс #наследование
Вопрос:
В приведенном ниже коде foo
возвращает объект типа A по значению. Могу ли я как-то преобразовать это без удобного взаимодействия в объект типа B? (Примечание: класс A включает в себя все компоненты данных / хранилища, класс B просто вводит больше методов)
class A{
/*data*/
A foo(...);
};
class B: public A
{
/*no-data*/
B doMagic(...);
};
/*usage*/
B bone;
B btwo = bone.foo(...) /*wo cast*/
Заранее спасибо!
Комментарии:
1. Я честно пытаюсь, но я не могу понять, чего вы хотите, основываясь на том, как вы это сформулировали. Не могли бы вы добавить еще немного информации и изменить ее формулировку?
2.
class B, public A
должно бытьclass B : public A
. Кроме того, вам нужно возвращать объект по значению или вы могли бы довольствоваться возвращаемыми (интеллектуальными) указателями?3. Я не очень хорошо понял ваш вопрос, но похоже, вам нужен какой-то полиморфизм, может быть?
4. В чем ваша проблема? За исключением опечатки
class B, public A
все выглядит нормально.
Ответ №1:
Вы не можете, и это не имеет смысла в том виде, в котором вы это написали; и вы также получили синтаксические ошибки.
Вы не можете преобразовать фактические базовые объекты в производные объекты, и обычно вы также не можете разумно пойти другим путем. Обычная вещь, которую вы можете сделать, это преобразовать указатели и ссылки.
В вашем случае вы обычно использовали бы ковариантное возвращаемое значение для виртуальной функции:
struct A
{
virtual A * foo();
};
struct B : A
{
virtual B * foo(); // OK, this _overrides_ A::foo()
};
int main()
{
B x;
B * p = x.foo(); // no cast
}
Вам нужно будет тщательно продумать многие, многие детали при использовании этого подхода. Это, безусловно, возможно, но вы должны многое сделать правильно. Вероятно, вам понадобится пара пользовательских конструкторов, чтобы заставить B::foo()
делать что-нибудь разумное.
Ответ №2:
Я не думаю, что вы можете. A::foo
возвращает A
, вот как это определено, вот что это делает. Даже несмотря на то, что B
не содержит дополнительных данных, я не думаю, что C может это знать.
Пара альтернатив, которые вы могли бы попробовать вместо этого:
Есть B
contstractor, который создается из параметра A. Хотя я предполагаю, что это фактически приведение.
class B, public A
{
/*no-data*/
B( const Aamp; param );
B doMagic(...);
};
/*usage*/
B bone;
B btwo = bone.foo(...);
Или другая стратегия, сделайте doMagic
статический метод, который работает с A
параметром. Я предполагаю, что весь смысл этого в том, что вы хотите запустить doMagic метод для результата A::foo
class B, public A
{
/*no-data*/
static B doMagic(Aamp; param, ...);
};
/*usage*/
B bone;
A atwo = bone.foo(...);
B::doMagic( atwo, ... );
Не знаю, сработает ли это для вас, но, надеюсь, они помогут.
Комментарии:
1. Это стиль C, у меня уже есть склонности к этому, но это разрушает всю концепцию C … (не говоря уже о руководствах по кодированию)