Thread: Scenegraph derived class vector c++ custom behaviour

  1. #1
    Registered User
    Join Date
    May 2015
    Posts
    2

    Scenegraph derived class vector c++ custom behaviour

    I am trying to create a scenegraph with a vector of Base class pointer with different type of derived classes and their own behaviours. Now here is my question:

    Code:
    class Base
    {
    public:
        virtual void setParent(Base* pParent);
        virtual void addChild(Base* pChild);
        // for simplicity I wont implement all functions
    private:
        Base* m_pParent;
        std::vector<Base*> m_pChildren;
    };
    
    classDerivedOne:publicBase
    {
    public:
        // virtual function override
        int custom(){return1337;}
    }
    classDerivedTwo:publicBase
    {
    public:
        int customtwo(){return1337+1;}
    }
    main(xyz)
    {
        DerivedOne* d1 =newDerivedOne();
        DerivedTwo d2 =newDerivedTwo();
        d1->addChild(d2);
        for(auto e : d1->getChildren())
        {
            std::cout <<static_cast<DerivedOne*>(e)->custom(); std::endl;// returns 1337 twice instead of once
        }
    }


    Now my question is how do I realize the above? How can I call a specific function if the node is of a specific type? I want to create a scenegraph that can hold a variety of different node-types and some must not be rendered, so I am really curious to see if there is some way to realize this idea? The problem is that at the moment, if I cast a base to a derived class and call the function, the function is executed even when originally the class wasnt of that derived class.

    Last edited by KevinExtremo; 05-27-2015 at 11:59 AM.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by KevinExtremo
    Now my question is how do I realize the above? How can I call a specific function if the node is of a specific type?
    Perhaps the custom function (with customtwo replaced by custom in DerivedTwo) should be declared virtual in Base, either pure virtual, or with some default implementation (or even both, but that tends to be rare).

    Quote Originally Posted by KevinExtremo
    The problem is that at the moment, if I cast a base to a derived class and call the function, the function is executed even when originally the class wasnt of that derived class.
    Technically, you have undefined behaviour when you do that. If for some good reason you really need to cast the base class pointer to a derived class pointer type, use dynamic_cast. This way, you will get a null pointer if the object is not of the destination derived class type.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    May 2015
    Posts
    2
    Quote Originally Posted by laserlight View Post
    Perhaps the custom function (with customtwo replaced by custom in DerivedTwo) should be declared virtual in Base, either pure virtual, or with some default implementation (or even both, but that tends to be rare).
    So, let me get this straight. You mean I should declare it a pure virtual and call it no matter if the class actually has such a method or not and simply blast the call off to a virtual on those that dont?

    Quote Originally Posted by laserlight View Post
    Technically, you have undefined behaviour when you do that. If for some good reason you really need to cast the base class pointer to a derived class pointer type, use dynamic_cast. This way, you will get a null pointer if the object is not of the destination derived class type.
    So, does that mean technically I could simply dynamic_cast every single element against a certain class and if the pointer exists it is of that type? Couldn't I use this method to call the functions? e.g:

    Code:
    for(auto e : d1->getChildren())
    {
        DerivedOne* d = dynamic_cast<DerivedOne*>(e);
        if(d) { d->custom(); }
    }

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by KevinExtremo
    So, let me get this straight. You mean I should declare it a pure virtual and call it no matter if the class actually has such a method or not and simply blast the call off to a virtual on those that dont?
    No, what I mean is that you should design the base class such that you can call a virtual function, hence making use of the polymorphism associated with such a class hierarchy formed by inheritance. For example, this should just work:
    Code:
    for (auto e : d1->getChildren())
    {
        std::cout << e->custom() << std::endl;
    }
    e would be a pointer to Base, but because both DerivedOne and DerivedTwo override custom (or use the default implementation from Base), you get the right behaviour for the subclass that is the type of the object that e points to, whatever it is.

    Quote Originally Posted by KevinExtremo
    So, does that mean technically I could simply dynamic_cast every single element against a certain class and if the pointer exists it is of that type? Couldn't I use this method to call the functions? e.g:
    Yes, but that is typically a poor approach. It may indicate that your base class interface is badly designed, or that you should not be trying to iterate over the derived class objects via a pointer to the base class, or that you really need double dispatch and hence should consider the visitor pattern.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Creating custom class for vector of pairs
    By Mr_Miguel in forum C++ Programming
    Replies: 3
    Last Post: 10-07-2009, 07:04 PM
  2. Replies: 8
    Last Post: 03-19-2008, 03:04 AM
  3. vector derived class, help
    By TriKri in forum C++ Programming
    Replies: 14
    Last Post: 10-04-2007, 04:46 AM
  4. custom class vector
    By -=SoKrA=- in forum C++ Programming
    Replies: 9
    Last Post: 07-08-2003, 01:14 PM
  5. help on some vector of custom class code
    By cozman in forum C++ Programming
    Replies: 1
    Last Post: 08-09-2001, 11:55 PM