类型转换为基类后无法调用方法
Posted
技术标签:
【中文标题】类型转换为基类后无法调用方法【英文标题】:Not able to call method after typecasting to base class 【发布时间】:2013-04-19 12:01:07 【问题描述】:我有 Ball
类,它派生自 PhysicsObject
类。在以下方法中,我从void
指针获取Ball
实例并检查其类型是否为PhysicsObject
。当我调用collidingWith
方法时,它不会在Ball
类对象中被调用。我在这里做错了什么?
更新 我在底部添加了sscce。请参考。
代码
void Levels::BeginContact(b2Contact *contact)
b2Fixture *fixtureA = contact->GetFixtureA();
b2Fixture *fixtureB = contact->GetFixtureB();
void *objA = fixtureA->GetUserData();
void *objB = fixtureB->GetUserData();
PhysicsObject* physicsObjA = reinterpret_cast<PhysicsObject*>(objA);
PhysicsObject* physicsObjB = reinterpret_cast<PhysicsObject*>(objB);
if ((physicsObjA != 0) && (physicsObjB != 0))
physicsObjA->collidingWith(physicsObjB); //not working
physicsObjB->collidingWith(physicsObjA);
物理对象
#ifndef PHYSICSOBJECT_H_
#define PHYSICSOBJECT_H_
class PhysicsObject
public:
PhysicsObject();
virtual ~PhysicsObject();
virtual void collidingWith(PhysicsObject *obj) = 0;
;
#endif /* PHYSICSOBJECT_H_ */
球.h
#ifndef BALL_H_
#define BALL_H_
#include "Box2D/Box2d.h"
#include "cocos2d.h"
#include "PhysicsObject.h"
class Ball : public PhysicsObject
public:
//other methods
void collidingWith(PhysicsObject *obj);
;
#endif /* BALL_H_ */
球.cpp
void Ball::collidingWith(PhysicsObject *obj)
CCLOG("Ball::collidingWith"); //this method is not being called
//other methods
Ball::Ball()
//other code
b2FixtureDef ballShapeDef;
ballShapeDef.userData = this;
//other code
更新
我还有 3-4 个其他类是从 PhysicsObject
派生的,就像 Ball
一样,我在这里没有提到,但通用代码是相同的。
更新 SSCCE
在main.cpp
的foo()
在baseObjA->collidingWith(baseObjA);
出现错误
基类
class Base
public:
Base(void);
virtual ~Base(void);
virtual void collidingWith(Base *obj) = 0;
;
另一个基类
class AnotherBase
public:
AnotherBase(void);
~AnotherBase(void);
virtual void foo();
;
派生类头
#include "Base.h"
#include "AnotherBase.h"
class Derived :
public AnotherBase, Base
public:
Derived(void);
~Derived(void);
void collidingWith(Base *obj);
;
派生类实现
#include "Derived.h"
void Derived::collidingWith(Base *obj)
printf("Ball::collidingWith");
main.cpp
#include "Derived.h"
void myFoo(void* userData);
int _tmain(int argc, _TCHAR* argv[])
Derived *derived = new Derived();
void* userData = derived;
myFoo(userData);
return 0;
void myFoo(void* userData)
Base* baseObjA = reinterpret_cast<Base*>(userData);
if (baseObjA != 0)
baseObjA->collidingWith(baseObjA);// Error here
【问题讨论】:
你试过投射到Ball
吗?
@AdriC.S.不,我没有,实际上我需要这种方式,因为还有其他类,如 Ball
派生自 PhysicsObject
你怎么知道是Ball
?球从哪里来?如果您将Ball
分配给PhysicsObject
,您可能已经对其进行了切片。
你能提供sscce吗?
您是否 100% 确定 GetUserData()
调用实际上返回了指向 PhysicsObject
的指针?
【参考方案1】:
在 box2d 中从 void* 铸造也给了我非常相似的问题。
似乎reinterpret_cast
会导致错误,因为collidingWith
是一个虚拟方法。 (如果方法不是虚拟的,你应该可以毫无问题地调用它)。
我已经解决了这个问题:
void* data; // You know it's type is Base
Base* base = static_cast<Base*>(data);
Derived* derived = dynamic_cast<Derived*>(base);
derived->collidingWith();
【讨论】:
你能投票吗?如果您需要,我会添加更多解释:)以上是关于类型转换为基类后无法调用方法的主要内容,如果未能解决你的问题,请参考以下文章