Наследование C и возвращаемые значения метода

#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 … (не говоря уже о руководствах по кодированию)