Easy Way to give All of my classes the same Private Variable?

Started by
17 comments, last by BitMaster 10 years, 2 months ago

Yep. I've only used it twice before, and both times I felt slightly proud and slightly disgusted at the same time. laugh.png

Advertisement

one question: what is the difference, or the point of having two constructors:


Counted() {
      ++number_of;
    }
Counted(const Counted &) {
      ++number_of;
    }

One is a copy constructor which can be invoked in several circumstances.


A a;  // Normal constructor.
A b( a ); // Copy constructor.
A c = a; // Copy constructor.
 

L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

Curiouser and curiouser...
void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.

There may be a more general solution to your problem, and that is to use Entity Component System design pattern. In principle:

  1. The Entity is a general purpose object. Usually, it only consists of a unique id and a container.
  2. The Component consists of a minimal set of data needed for a specific purpose. In your example, you would have a "Visible" component and a "Physical component".
  3. The System manages the behavior of the components.

In your example, a human would be an Entity with a "Visible" and a "Physical" component attached to the container. A Component can have a state, but it doesn't have to.

And then you would have one system that manages all Entities that use the "Physical" components, and another system that manages all entities with "Visible" components. These systems would be independent of each other. There may be variations, where a System need to access entities that consists of a combined list of components.

See Anatomy of a knockout and Refactoring Game Entities with Components for more information. I think the https://github.com/alecthomas/entityx source code looks promising. It also has a good support for using events to communicate information between systems (and other modules), instead of having components know about other components.

The disadvantage of the ECS may be that it adds some code initially, and it also adds some communication overhead. If you have a small system with not much more than stated above, then ECS will probably be an overkill. The advantage is that it has a very high degree of flexibility. It is much easier to add functionality, and provide alternative functionality.

[size=2]Current project: Ephenation.
[size=2]Sharing OpenGL experiences: http://ephenationopengl.blogspot.com/

Hmm, ECS seems interesting, so according to my research, I would have Human( an entity) and instead of inheriting visible and physical, it has instances of visible and physical?

Hmm, ECS seems interesting, so according to my research, I would have Human( an entity) and instead of inheriting visible and physical, it has instances of visible and physical?

Right. Now suppose you have a drawing function. This would be a "System" that iterates through all entities that have both a physical and a visible component, and draw them. The visible component could typically have some information about how a thing should look like (e.g. human, monster, sparks flying around, flying arrow), and use the physical component to know where to draw it.

Another system could be a collision detection. It would iterate through all entities that have a physical component, as it wouldn't care how the entity is drawn. This system would then detect "arrows" that collide with "monsters", and generate an event when that happens. It shouldn't need to understand what an arrow is, and what it means when another object is hit by an arrow.

Yet another component could be health data, and a system that manages health. Health components would be attached to the human and monster entities, but not to arrow entities. The health management system would subscribe to the event generated from collisions and update health accordingly. This system could also now and then iterate through all entities with the health component, and regenerate health.

Of course a real game is much more complicated than this, and there are new design problems to solve. But I think the ECS way is interesting. Using events isn't part of the original ECS pattern, but I think it is convenient and will decouple dependencies.

[size=2]Current project: Ephenation.
[size=2]Sharing OpenGL experiences: http://ephenationopengl.blogspot.com/

If is a larger software, take a look at the Component Based Entity System Architecture. Can be a little off-topic, but can save your time if you are interested to get a modular engine.

There's the CRTP:
[spoiler]







template <typename T>
class Counted {
  protected:
    Counted() {
      ++number_of;
    }
    Counted(const Counted &) {
      ++number_of;
    }
    ~Counted() {
      --number_of;
    }

    static int number_of;
};
template <typename T>
int Counted<T>::number_of = 0;

class Human : private Counted<Human> {
  // whatever
};

class Girl : public Human, private Counted<Girl> {
  // whatever
};
[/spoiler]


For completeness sake, what would you have to do to make that C++11-friendly. From my understanding (and unfortunately I still haven't found the time to get enough practical experience in to feel secure) inheriting from this class would prevent automatic move-constructor generation. However, adding



Counted(Counted&& other)
{
  ++number_of;
}
Counted& operator = (Counted&&) = default;
should fix that, shouldn't it?

This topic is closed to new replies.

Advertisement