Kann ich warf ein Objekt der Klasse zum interface-Zeiger in der es implementiert?
Ich habe eine interface-Klasse, wie die folgenden.
class IRecyclableObject
{
public:
virtual ~IRecyclableObject() {}
virtual void recycle() = 0;
virtual void dump() = 0;
virtual int getRecycleTypeID() = 0;
};
Das folgende ist meine CharacterAI Klasse, die erbt, und eine andere Klasse und implementiert die oben genannten interface-Klasse. Es ist wie folgt definiert.
class CharacterAI : public harp::Character, public harp::IRecyclableObject
{
public:
CharacterAI();
virtual ~CharacterAI();
...
//-- note these 3 virtual functions -- //
virtual void recycle();
virtual void dump();
virtual int getRecycleTypeID();
...
};
Diese drei virtuellen Funktionen, wie definiert in der Schnittstelle, habe ich implementiert, die es normalerweise in CharacterAI Klasse. Nichts bildet sich ein, geht es.
Es ist an der Zeit, wenn ich Sie in Verwendung mit ObjectPool (self-made) - Klasse, in der die Speicherung der Daten der verfügbaren Objekte in
m_freeList
verwendet CCArray Klasse.
Das problem tritt in den folgenden code.
IRecyclableObject* ObjectPool::popFreeObjectAndAddToActiveListForType(int recycleTypeID)
{
//search from free-list
for(unsigned int i=0; i<m_freeList->count(); i++)
{
IRecyclableObject* obj = (IRecyclableObject*)m_freeList->objectAtIndex(i);
CharacterAI *obj1 = (CharacterAI*)m_freeList->objectAtIndex(i);
CCLog("recycleTypeID : %d %d %d", obj->getRecycleTypeID(), recycleTypeID, obj1->getRecycleTypeID());
...
}
return NULL;
}
Das erwartete Ergebnis ist, zu zeigen,
recycleTypeID : 4 4 4
Aber ich habe
recycleTypeID : 524241408 4 4
Die erste ist eindeutig Müll dort und zufällig unterscheidet sich von jeder Schleife.
Ich habe versucht, einen Haltepunkt in die Funktion implementiert getRecycleTypeID() innen CharacterAI Klasse, bevor er zurückkehrt. Ich fand heraus, dass nur
obj1->getRecycleTypeID()
genannt wurde, aber nicht anderen.
Durch die Fokussierung auf obj variable, Es ist deutlich zu erkennen, dass es scheint, anderes Objekt aufruft, die Funktion, und die Ursache kann von casting-ein Objekt-interface-Klasse und verwenden, wenn von dort aus, in denen es falsch oder in irgendeiner Form.
Was ist da Los?
Kann ich warf einen Objekt-Typ Klasse interface Klasse Zeiger (der es implementiert) und korrekt aufrufen von Funktionen, definiert im interface-Klasse?
- Was für ein Typ zurückgegeben wird
m_freeList->objectAtIndex()
? - Es ist CCObject*.
- Wie funktioniert
CharacterAI
Erben vonCCObject
durchharp::Character
? - Dito zu dem, was Andy gerade gefragt.
- Gibt es weitere virtuelle Funktionen in den ausgelassenen Teil CharacterAI?
- Ja, CharacterAI -> Zeichen> CCSprite -> CCObject am Ende.
- Das ist das problem. Schreiben Sie eine Antwort.
- was und wie speichern Sie in
m_freeList
? - ja, es ist noch eine virtuelle Funktion gibt.
- Hat der Charakter vielleicht auch Erben von IRecyclableObject?
- Ich store pre-initialized Objekte, bevor Sie diese Funktion ruft. Gehen Sie einfach durch die Schlaufe und speichern Sie Sie eins nach dem anderen.
- Ich weiß nicht, wie die Darsteller zu
IRecyclableObject *
es sollte nicht erforderlich sein, da das Objekt von einer Klasse abgeleitet von (in solchen asignments C++ bietet einige passen-den-Zeiger-auf-die-richtige-offset Tanz IIRC). - Nein, nur CharacterAI erbt IRecyclableObject.
- ObjectPool wird mit jeder Klasse, die IRecyclableObject, ich möchte es allgemein so viel wie möglich.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ja. Aber das ist nicht Ihr Fall. Funktion
objectAtIndex()
gibt einen Zeiger auf eineCCObject
, und diese Klasse definitiv nicht nicht Umsetzung derIRecyclableObject
- Schnittstelle.So, ein brutaler C-style cast von
CCObject*
zuIRecyclableObject*
wird in Folge verlieh das layout ein Objekt von der ehemaligen Art, als ob es war ein Objekt der letztere Typ. Das ist schlecht und führt zu Undefiniertes Verhalten.Sollten Sie verwenden
dynamic_cast<>
zu werfen Sie IhreCCobject*
zu einemIRecyclableObject*
:Beachten Sie jedoch, dass dies gar nicht nötig, wenn Sie nur wollen, dass Ihre Zeiger zu sein, schließlich Stimmen, um ein Objekt des Typs
CharacterAI
. Nur direkt es Stimmen, die für diesen Typ:dynamic_cast<>
gibt einen null-Zeiger, wenn der laufzeittyp des Objekts verweist der Zeiger, die Sie versuchen zu casten ist nicht (gleich oder abgeleitet) den Ziel-Typ von den Kopf hängen. Daher wird in diesen Fällen, in denen Sie nicht sicher sind, über den konkreten Typ der den Spitzen Gegenstand, vergessen Sie nicht zu überprüfen, ob der zurückgegebene Zeiger nicht null ist, bevor die Dereferenzierung es.dynamic_cast
und anderen casting-Typ, nicht nur c-style cast. Es ist über RTTI und Laufzeit ich beschäftige mich mit ihm an diesem problem. Jetzt Zahl ich meinen Teil des Problems in andere codes. Danke!