문제

I've read a lot of things on the virtual functions, but I'm still not able to get something to work how I want.

Basically, I've got the following class:

class Body
{

    protected:
        scene::ISceneNode* Model;
        virtual void setModel();
    public:
        Body( core::vector3df Position, core::vector3df Rotation );
};


Body::Body( core::vector3df Position, core::vector3df Rotation )
{
    CurrentThrust = 0;
    setModel();
    Model->setPosition( Position );
    Model->setRotation( Rotation );
}

void Body::setModel()
{
    Model = Engine::Instance->GetSceneManager()->addCubeSceneNode();
    Model->setMaterialFlag( video::EMF_LIGHTING, false );
}

I am create new classes inheriting Body, and the idea is that I override "setModel()" in those classes, and the constructor will load my new model, instead of the default; like below

class Craft : public Body
{
    protected:
        virtual void setModel();
    public:
        Craft( core::vector3df Position, core::vector3df Rotation );
};

Craft::Craft( core::vector3df Position, core::vector3df Rotation ) : Body(Position, Rotation)
{
    // Other stuff
}

void Craft::setModel()
{
    Model = Engine::Instance->GetSceneManager()->addAnimatedMeshSceneNode( Engine::Instance->GetSceneManager()->getMesh("resource/X-17 Viper flying.obj") );  // addCubeSceneNode();
    Model->setMaterialFlag( video::EMF_LIGHTING, false );
    Model->setScale( core::vector3df(0.1f) );
}

However, it always creates a Cube model instead of my Viper mode when I create a new instance of Craft.

Is it possible to get virtual functions to work like I'm thinking? or do I need to just change my constructors to create the models in their respective classes?

Thanks

도움이 되었습니까?

해결책

Is it possible to get virtual functions to work like I'm thinking?

No. When you call one from a constructor, it's dispatched according to the class being initialised (Body in this case), not the final overrider (since that hasn't been initialised yet, so can't be accessed safely).

or do I need to just change my constructors to create the models in their respective classes?

That's probably the simplest solution. I'd suggest passing the model as a constructor argument to Body. That way, it's impossible to forget to set it.

다른 팁

class Craft : public Body
{
    protected:
        void setModel();
    public:
        Craft( core::vector3df Position, core::vector3df Rotation );
};

Don't use the keyword virtual in the Class Craft.

Like mathematician1975 pointed out, you should never use a virtual method inside a constructor or a destructor.

An object being built by a constructor cannot be considered of the constructor's class until the control flow leaves the constructor. Whenever you will call a virtual method inside of Craft's constructor, you will always end up invoking a Body's method.

Since setting your models means loading a mesh from a file, which is usually a quite expensive operation, I suggest that you do not do it until you really need it, i.e. whenever your model is requested. At this point, your virtual should behave like you expect it to.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top