[英]Getting derived class from base method
我有3類Entity
, Character
和Item
。 當我做
Character * Player = new Character(QRectF(0, 0, 50, 50), "player", theScene);
Player->setVelocityX(30)->setAttackPoint(10);
編譯器告知該error: 'class Entity' has no member named 'setAttackPoint'
。 我該如何使Entity* setVelocityX(qreal vx);
返回一個Character
指針或一個Item
指針?
。
class Entity : public QObject, public QGraphicsPolygonItem
{
Q_OBJECT
public:
Entity();
Entity(qreal x, qreal y, qreal w, qreal h, QString tag, QGraphicsScene *scene = 0, QGraphicsItem *parent = 0);
Entity(QRectF position, QString tag, QGraphicsScene *scene = 0, QGraphicsItem *parent = 0);
Entity(QString tag, QGraphicsScene *scene = 0, QGraphicsItem *parent = 0);
Entity* setVelocityX(qreal vx);
// etc
}
class Character : public Entity
{
Q_OBJECT
public:
Character(qreal x, qreal y, qreal w, qreal h, QString tag, QGraphicsScene *scene = 0, QGraphicsItem *parent = 0);
Character(QRectF position, QString tag, QGraphicsScene *scene = 0, QGraphicsItem *parent = 0);
Character(QString tag, QGraphicsScene *scene = 0, QGraphicsItem *parent = 0);
Character* setAttackPoint(int attackPoint);
//etc
}
class Item : public Entity
{
Q_OBJECT
public:
enum ItemType{
Consummable,
Special,
Weapon
};
Item(QString name, qreal x, qreal y, qreal w, qreal h, QString tag = "item", QGraphicsScene *scene = 0, Character *parent = 0);
Item* setOwner(Character* newOwner);
//etc
}
如果您絕對確定類型(否則,請使用dynamic_cast並檢查結果指針是否為非nullptr):
reinterpret_cast< Character * >( Player->setVelocityX(30))->setAttackPoint(10)
另外,根據您的代碼,您是否可以代替,或者函數調用的順序是否重要?
Player->setAttackPoint(10)->setVelocityX(30)
Character* player = new Character(QRectF(0, 0, 50, 50), "player", theScene);
dynamic_cast<Character*>(player->setVelocityX(30))->setAttackPoint(10);
順便說一句,此方法類型不安全。 您需要添加一些控件。
通常, SETS方法用於設置一些值,而不是返回對象。
Character* player = new Character(QRectF(0, 0, 50, 50), "player", theScene);
Entity* playerEntity = player->setVelocityX(30);
Character* isCharacter = dynamic_cast<Character*>(playerEntity);
if(isCharacter) {
isCharacter->setAttackPoint(10);
}
還有另一種方法可以實現您要執行的操作: 反復使用模板模式
基本思想是,基類具有一個模板參數,即派生類。 然后在每個派生類中實現一個非虛函數 ,然后可以使用static_cast這樣的調用(簡化的類布局):
Entity.h :
#include <iostream>
template<class DERIVED_CLASS>
class Entity
{
public:
void doStuff()
{
static_cast<DERIVED_CLASS*>(this)->doStuffDerived();
}
};
class Character : public Entity<Character>
{
public:
void doStuffDerived()
{
// implementation
std::cout << "character\n";
}
};
class Item : public Entity<Item>
{
public:
void doStuffDerived()
{
// implementation
std::cout << "item\n";
}
};
main.cpp :
#include "Entity.h"
int main()
{
// Instantiate a n Item object
Entity<Item> item;
item.doStuff();
// Instantiate a character object
Character character;
character.doStuff();
}
使用這種方法,您實際上沒有虛擬函數調用的開銷,但是可以為每個實現實現不同的行為,這有點像虛擬函數(好的編譯器可以輕松地將此代碼優化為僅對派生類進行函數調用) 。
而且您也不必依賴reinterpret_cast,如果可能的話,也應該避免這樣做。
這里是更多信息: 奇怪地重復模板模式
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.