C++中的多態性遇到一些麻煩。我試圖創建一個相當奇怪的語法來初始化一個類,但是當我從基類方法返回「this」時,它似乎失去了新創建的派生類。從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();
出於好奇,爲什麼函數返回一個'基地*'當你知道它的實際返回'富*'? – templatetypedef
添加虛擬析構函數,首先應刪除一個案例。 –
難道你不能只是超載Bar * Bar :: initWithPuppies調用Foo :: initWithPuppies裏面並返回這個? –