0

I am considering a problem and can't come to a conclusive "better" of the two options. It comes down to deciding whether a complex data member (ie, not a primitive) should be a pointer or simply a value. (Note, I have seen many questions about pointer vs reference for data members, but nothing regarding pointer vs value) The biggest things I'm weighing are

  1. Lifespan of the data member (whether it lives the full life of it's owner).
  2. In the case when it does last the full lifespan, reducing memory fragmentation.

Consider the following code:

class PlayerStatistic
{
    int m_MaxValue;
    int m_CurrentValue;
    // And many other things that round out a player statistic
}

class PlayerStatisticManager
{
    //While in this case, it may be better to store stats as a list of some kind and
    //identify them by a StatId or something, for this example, I'm declaring them 
    //individually.
    PlayerStatistic* m_pHealth;
    //OR
    PlayerStatistic m_Health;

    // And many more statistics.
}

In the above example, every player always has health. Their health statistic is ALWAYS the lifespan of the StatisticManager, which in turn is ALWAYS the lifespan of the player.

If this weren't the case, I would prefer the pointer, so that NULL can be indicative that the object doesn't exist (which might be better for a stat that not all players have).

However, because that's not the case, I think I would rather have it stored as value, in order to make fewer larger memory allocations, rather than many small memory allocations.

Is my thinking sound, or is there something I'm not considering?

Edit - My choice of words ("pointer vs value") was poor. What I meant was what one of the answers clarified:

What you are referring to here is weather it's better to have the mHealth statically or dynamically allocated;

Moreover, in this case, I know that health's lifespan is the player's lifespan, so my question basically comes down to memory. Is it better memory management to statically allocate data members in the interest of having fewer allocations, and instead doing one big allocation (when Player get newed).

tloch14
  • 61
  • 4
  • Depending on the size of your project, you might also want to consider that if you use pointers instead of values, the full class need not be in scope when declaring the class using it, i.e. `PlayerStatisticManager` in your example. This can reduce compile dependencies, which in large projects might lead to shorter compile times. I'd prefer the pointer for this reason (some kind of smart pointer to be precise). – blackbird Dec 05 '13 at 19:36
  • If the data in a class is optional due to 2 members of the same class being in clear-cut different categories (e.g. a pitcher and a hitter in baseball), you may want to look into using inheritance. You'd have one very basic player class and then inherit from it to make the pitcher and hitter classes e.g. – user904963 Dec 05 '13 at 19:39
  • @user904963, I would agree if I was going to be using inheritance that way. I was thinking something more along the lines of data-driven differences, such as classes in an RPG (special energy stats for certain classes or something). – tloch14 Dec 05 '13 at 19:50

3 Answers3

0

I think you got things a little miked up: "by reference" or "by value" refers to how you pass parameters to a function. By pointer, or by value is preferred because in that case only the pointer to a memory location is passed; for structures for example, all the members are copied to the stack - adding overhead.

What you are referring to here is weather it's better to have the mHealth statically or dynamically allocated; and that is a design question and depends on the application. Both ways are fine - but there is no ultimate better solution - it depends....

Pandrei
  • 4,843
  • 3
  • 27
  • 44
0

One thing you need to consider is how you are going to use the data. Whether you need it to be changed through various routines or simple monitor it in most processes.

If you indeed need to change it and expose the change to other routines, better pass it by reference in which case pointer would be a better solution.

On the other hand, if it is a simple value to be monitored and not changed often, I would suggest pass by value especially monitoring does not happen frequently.

In your case, the following is my analysis: 1. Player health may change frequently in case of event like a battle. The data is better passed by reference in this case. 2. Player health is monitored by a few processes infrequently when not in battle, like when the user is querying the health value. In this case, data is better passed by value so accidental change to the value would not affect the object instance itself.

Personally, I would use pointer in PlayerStaticManager. This gives the option of passing the value or reference in different scenarios. If you need to pass by reference, pass the pointer along. If you need to pass by value, make a copy of the content, pass it along and forget about the copy.

Hope this helps.

Xephon
  • 393
  • 1
  • 12
  • I think the words I chose to use may have been confusing. Pandrei's answer clears up what I meant to say, and I edited my question to clarify what my concern is -- that is, memory fragmentation. – tloch14 Dec 05 '13 at 19:47
  • Pandrei actually mistook by pointer as the same as by value. By pointer is a form of by reference as you'll be modifying the data itself in memory. By value means make a copy, pass it along. Clearly by pointer is not such case. To answer the "new" question, I would choose statical allocation. Values like mHealth, especially for players would be existed since the player is created until the player is completely deleted. Static makes more sense to me. – Xephon Dec 05 '13 at 19:49
0

Only use a pointer if the lifetime of the member will be different from the lifetime of the containing object.

aeagal
  • 31
  • 6
  • This is the line of thought I was leaning toward. I just wanted to be sure of *why*, especially considering memory management and fragmentation. – tloch14 Dec 05 '13 at 19:51
  • I will add that the only reason this is advantageous is because it helps prevent fragmentation by making memory management implicit. You can't mess up `new` and `delete` when you don't use them. – aeagal Dec 05 '13 at 20:08