Home > database >  What is the best type of pointers to use in this situation
What is the best type of pointers to use in this situation

Time:06-13

I'm currently making a small "Game Engine". I was wondering if I should use smart pointers and which type I should use. or do I just use raw pointers for this GameObject class. every instance of GameObject have Component attached to it Transform, sprite etc. should I use smart pointers or just raw pointers. because I have never used smart pointers and I always get a bunch of errors when I try to. will it be fine to use raw pointers?

GameObject.h:

class Component;
    class GameObject{
    public:
        GameObject();
        virtual ~GameObject();
        void addComponent(Component* component);
        
        //return the first component of type T
        template<typename T>
        T* getComponent(){
            for(auto component : components){
                if(dynamic_cast<T*>(component)){
                    return dynamic_cast<T*>(component);
                }
            }
        }

        // return the component with the type T
        template<typename T>
        std::vector<T*> getComponents(){
            std::vector<T*> components;
            for(auto component : this->components){
                if(dynamic_cast<T*>(component)){
                    components.push_back(dynamic_cast<T*>(component));
                }
            }
            return components;
        }

        void removeComponent(Component* component);
        
        std::vector<Component*> components;

    };

    //======================================================

    class Component
    {
    private:
    public:
        Component();
        virtual ~Component();
        
        //the game object this component is attached to
        GameObject* gameObject;
        
    };

Thanks for reading.

CodePudding user response:

First things first. In general early failure is preferred over late failure. Failure after delivery is catastrophy. The most welcome form of failure is at compile-time. Good code tried to prevent runtime or logic errors by asserting errors at compile-time. So don't be frightened by compile errors. Next, you have to make a decision on lifespan of your objects and their ownership. The main problem with raw pointers is the ambiguity of implication; does a raw pointer imply:

  1. Just a reference
  2. An optional reference
  3. An owned resource
  4. An array beginning
  5. PIMPL
  6. ...

It's hard to tell by looking at the code using raw pointers, which asspect was intended. Confusions during coding lead to all sort of evil(including resource leak, double delete, use-after-free ...).

Smart pointers on the other hand, limited the use case of pointed-to-object to a very specific case(from above list or else). Moreover, smart pointers provide guarantees about lifespan of the object. Standard library provides a variety of classes (smart pointer or else) for different use-cases above.

If none of those classes are appropriate for a specific use case, I would rather define a wrapper to encapsulate the pointer and decorate its behavior.

  • Related