Question

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

Was it helpful?

Solution

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top