Возникли проблемы с полиморфизмом в C ++.Я пытаюсь создать довольно странный синтаксис для инициализации класса, но, похоже, я теряю вновь созданный производный класс, когда возвращаю «this» из метода базового класса.
В псевдокоде нижеМне нужно, чтобы Base :: initWithPuppies () мог выполнять некоторые действия по умолчанию и возвращать производный класс, из которого он вызывается.
Я хочу иметь следующий синтаксис:
Bar *baz = (new Bar)->initWithPuppies();
Предпочтительно без с использованием шаблонов и необходимостью разыгрывать как:
initWithPuppies<Bar *>();
Да, я знаю, что это довольно странно.Но есть причина для этого, и «лучшие практики» не применяются в этой ситуации.Считайте, что это просто «что если».Я знаю, что вы, вероятно, должны:
Bar *baz = new Bar;
baz->initWithPuppies();
Но мне нужен прежний синтаксис.
Псевдокод:
class Base
{
// Kittens
};
class Foo : public Base
{
public:
Base * initWithPuppies();
virtual void test() = 0;
};
Base * Foo::initWithPuppies()
{
// Call to derived works
this->test();
return this;
}
class Bar : public Foo
{
public:
void test();
};
void Bar::test()
{
std::cout << "It Works!" << std::endl;
}
// Preferred syntax
// This gives "cannot convert from 'Base *' to 'Bar *' "
Bar *baz = (new Bar)->initWithPuppies();
baz->test();
/*------------------------------------------*/
// This gives " 'test' : is not a member of 'Base' "
Base *baz = (new Bar)->initWithPuppies();
baz->test();
/*------------------------------------------*/
// This gives "Base is not a polymorphic type"
UIBar *man = dynamic_cast<UIBar *>((new UIBar)->initWithFrame());
baz->test();
РЕДАКТИРОВАТЬ:
Если бы было так или иначе возможно иметь этот синтаксис:
Bar *baz = (Bar::create())->initWithPuppies();
Это было бы еще лучше, но я не мог понять, как создать в базовом классе новый экземпляр объектаполучено без вписывания типов:
Bar *baz = (Bar::create<Bar *>())->initWithPuppies();
МОЙ ОТВЕТ: (не могу ответить на свой в течение 8 часов)
Хотя Николь Болас прав и, как я сказал, синтаксисЯ хочу использовать это плохую практику, если вам действительно нужно использовать такой же синтаксис, как я (не спрашивайте ...), тогда вы можете сделать это:
class Base
{
// Kittens
};
class Foo : public Base
{
public:
virtual void test() = 0;
private:
void _initWithPuppies();
};
void Foo::initWithPuppies()
{
// Do shit
}
class Bar : public Foo
{
public:
Bar * initWithPuppies();
void test();
};
Bar * Bar::initWithPuppies()
{
this->_initWithPuppies();
return this;
}
void Bar::test()
{
std::cout << "It Works!" << std::endl;
}
Bar *baz = (new Bar)->initWithPuppies();
baz->test();