2

I have a general class Player and inside the class I declare an object of a smaller class, for example, Weapon, Inventory etc.

Naturally I have use pointers (shared_ptr) to instantiate my Player objects and used the same method to instantiate any object withing my class. Should I keep on doing this or should I try to make it more simple by not using pointers and will this come with a certain disadvantage?

class Player: public Human, public Control
    {
    public:
        Player();
       ~Player(){};

    private:
        Weapon           myWeapon;
        std::vector<std::tr1::shared_ptr<Weapon> > WeaponsList;

    };

vs.

class Player: public Human, public Control
    {
    public:
        Player();
       ~Player(){};

    private:
        Weapon           myWeapon;
        std::vector<Weapon> WeaponsList;

    };

Note, I use shared_ptr and want to keep an option to have Weapon to be a base class at some point (but no rush!).

8
  • Is Weapon a polymorphic type? Commented Oct 26, 2015 at 15:51
  • 1
    Err... wouldn't a constructor of class Player be called Player(), not gPlayer()? Why is MountWeapon() working on ints but myWeapon of type Weapon? Why is the member public? Why is rWeapon() returning a non-const reference to a member? Why is the use of pointers a "naturally"? Why is Draw() a member of Player? Ohmagawd... :-D Commented Oct 26, 2015 at 15:51
  • Not yet, I try to keep it simple, but it has an "Ammo" object within. I want to keep the option open to have it polymorphic at some point though. Commented Oct 26, 2015 at 15:53
  • @DevSolar: Too many questions.. don't take out the code without knowing what's inside and stick to the question. I have 42k lines of code working just fine with 20k objects behaving beautifully, colliding and shooting and a stable 120 fps rate. Commented Oct 26, 2015 at 15:58
  • 2
    @DevSolar. No offence taken. Note there is a difference between working on a code that needs to be maintained, such as working in a studio and being readable by others, and hobby programming. I have worked for 5 years on this project (sporadically) and had no trouble to get back to it, even a break of a year. In 42k of code, the engine runs smooth and I have encountered no bugs so far. If, at future, when I plan to extend it, it starts to fall apart, I will reconsider and think more about a flawed game design. Commented Oct 26, 2015 at 16:19

2 Answers 2

2

Definitely the former (ie yes, keep using pointers), just make sure you define a flexible abstract class Weapon with all the methods / attributes that your player will need to interact with; you want to avoid resolving the derived type as much as possible (this makes the code messy and a bit slower).

If you are not familiar with design patterns, I would encourage you to read about Factories and how they can be used to handle allocation in such cases. This will make your code easy to maintain/understand, should someone want to add another weapon to your game later on. You will want to use named tags to clarify your code and select the object to build in your factory; this can be done using enums, but I tend to prefer namespaces or structures if you can't use strongly-typed enums (c++11), eg:

struct WeaponID
{
    static const int DESERT_EAGLE = 0;
    static const int SHOTGUN = 1;
} 
// ... use in a switch/case e.g. WeaponID::SHOTGUN

You can easily see how such tags could be used in a switch and output a shared pointer to an abstract class (you can even define alias tags if needed).

If you suspect you might need to resolve derived types often, then consider storing the previous tag as a member of the abstract class, this will make it much easier and cleaner than using dynamic_casts for instance.

If you are concerned about performance (which, at 120 fps I imagine you are), consider using memory pools of objects (weapons, players, etc), although in the context of a game, I would expect the quantity of objects to be (almost) constant by the time the game begins?

Sign up to request clarification or add additional context in comments.

5 Comments

Yes, I keep the quantity constant and reserve the memory. Objects are initialised before the actual game starts. I like your idea of abstract classes. Weapons is a flexible class that is added via an external file that is read. I use enums for my weapons, but not shown it here.
I avoid dyanmic cast. I create a secondary lists with pointers to the objects I need (e.g. controllable objects) and work with them. I cringe at dynamic casts, maybe unjustifiably so and have only very few calls as an exception.. dunno, what do you think?
@user2856452 I think dynamic_casts are not meant to be used often by essence. It's good to keep away from them when you can, and as I said, it is easy to plan ahead and store IDs if you know you will need to resolve derived classes often.
Yes, which goes back to the discussion of game design with foresight. There are a few things I even feel they are wrong (like dynamic casts) but others, such as sigletons I am perfectly fine with as I they actually simplified my code as I take care to minimize their disadvantage. Generally, I am not dogmatic about game design, as long it does it deed for me for the purpose ahead.
I just read about factories as you proposed. I had this (or a similar) implementation in my game (didn't know it was called like factory). Basically I read from a file created by my game editor, that parses it into enums and passed to a "factory" function to return the right object to be added to a generic baseclass list. I faced no issues with that and of what I understand, this seems to be similar to what factoring is supposed to be.
2

With the information originally provided, I think the only answer is "It depends".

  • If your WeaponsList is a vector of pointers, what is responsible for clearing the various Weapon objects?
  • If WeaponsList is a vector of Weapon, you need to ensure the copy constructor is complete.
  • What is Weapon? Is it a base class from which you will derive Sword, Dagger, Lance, etc.? Or will the type of weapon merely be a property of the object?
  • Can a Weapon object exist without a Player? Will there be a shared list of weaponry that all Player objects point to?

In other words, I don't think we have enough detail to fully answer your question.

Update

With the additional information provided in a comment:

If you create an object, it needs to be cleared (destroyed); as you're using shared_ptr, that should be handled automatically.

As a Weapon can exist without a Player and may become a base class in the future, using a vector of pointers is probably the way to go.

3 Comments

Point 1: It's a shared_ptr. Do I have to clear it? Point 2: (same as Point 1) Point 3: Weapon stands currently by itself, it may become polymorphic at some stage later. Point 4: Yes, it can
@user2856452; Updated my answer based on your comment.
Thanks, that a good answer! Yes, that's what I thought. It depends of I want to have Weapon to be in future a base class. Cheers..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.