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();
那会更好,但是我不知道如何在基类中创建create而不进行类型转换的派生新实例:
Bar *baz = (Bar::create<Bar *>())->initWithPuppies();
我的答案:(我自己无法回答8个小时)
尽管Nicol Bolas是正确的,并且正如我所说的,我想使用的语法是不好的做法,但是如果您确实确实需要使用与我类似的语法(不要问...),则可以执行以下操作:
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();
最佳答案
我想要这样的语法:
Bar *baz = (new Bar)->initWithPuppies();
好,就在那儿停下来那不是您想要的语法。构造函数存在于C ++中是有充分的理由的,除非有充分的理由绕过它们,否则应使用它们。
如果由于某种原因不能使用构造函数,请使用工厂函数:
Bar *baz = Bar::initWithPuppies();
它将完成对象的分配和初始化,因此您不必直接使用
new
。至于错误的原因,是因为您不能隐式上变频。从继承的性质来看,所有
Bar
对象也是Base
对象。因此,C ++将隐式将指向派生类的指针转换为指向基类的指针。反之则不成立:Base
类并非自动成为所有Bar
类。因此,C ++为尝试向上转换继承层次结构将正确地给您一个错误。您必须显式使用
dynamic_cast
进行这种转换。您可以使用C样式的强制转换或static_cast
,但是只有当您完全确定类型是您期望的类型时,它们才起作用。关于c++ - 从C++中的基类返回派生的“this”的多态性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7341975/