3

Given the class:

class A { Public: void foo() { static int i; i++; } }; 

How would you change it to prevent i from changing between instances following this example:

A o1, o2, o3; o1.foo(); // i = 1 o2.foo(); // i = 1 o3.foo(); // i = 1 o1.foo(); // i = 2 

i.e. allocate memory for i on every instance.

EDIT:

Yes, you can add i as an instance variable, but what if you need these counters in various (independent) functions ? I am looking to limit the scope of the variable only to the function ("in member functions"). It would seem awkward to add variables such as i, c, counter, counter_2 to the class if you need various counters, would it not ?

6
  • 4
    .... that's what instance variables are for Commented Mar 7, 2019 at 16:15
  • 1
    static variables are what you do when you don't want unique instances. If you want to preserve a state per-instance of a class then you need to store that state as a member of the class. Commented Mar 7, 2019 at 16:17
  • 1
    Upvoted. This question is weird but not necessarily poor. Commented Mar 7, 2019 at 16:18
  • Think about what would happen if this did work the way you'd like: The "static" variable inside the member would have to be stored in part of the object instance to be instance-specific, but in C++ you usually declare the class separately from the member implementations and the class declaration has to be enough to allow the compiler to calculate the size of the object. Since the "static" variable is declared inside a method and not in the class definition, its size is not known by code that can only see the definition. Therefore we have a contradiction and this cannot work that way. Commented Mar 7, 2019 at 16:23
  • Related: stackoverflow.com/questions/6223355/… Commented Mar 7, 2019 at 17:48

2 Answers 2

5
class A { public: int i = 0; void foo(){ ++i; } }; 

is the normal way: i is now a member variable of the class. Clearly you don't want to use static.

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

1 Comment

I would make i private though
1

In circumstances where declaring data members become costly(need for sparse members that are not used so often), An instance indepent collection - normally an associative one - may come in handy. Knowing nothing more about the OP's intention, std::map family of classes can be used as first speculation. We need to have one counter per visited object in A::foo, but not for unvisited instances(i.e. A instances not calling A::foo). This was the the simplest first solution I came up with:

void A::foo(){ static std::map<A*,std::size_t> i; ++i[this]; //... }; 

Upon call to std::map::operator[] on an object not in the map, the associated value is default constructed in a memory location already zeroed by the allocator( in short words 1st-timers are automatically initialized to 0).

5 Comments

@RamGhadiyaram progammers hate typing😅
Have an upvote. This has an elegance to it which is particularly pertinent following the OP's edit. Consider const A* though as the key? Of course though the map could grow to be large if there are many instantiations of A and subsequent calls of foo. But that's fixable, although I'd imagine the overhead is comparable to the separate class members of the simpler approach.
@Bathsheba agreed. But associative containers are intended to implement sparse matrices. Moreover I just imply the interface of 'std::map'. But again any similar approach is only useful when 'A::foo' is rarely used compared to number of 'A' instances
-1 This is not safe. It is very likely that multiple instances of A could live at the same address at different times. Consider something as simple as a local variable on the stack of a function called multiple times, or a new heap allocation that gets freed and immediately reused.
Example of how many different ways this can go wrong: godbolt.org/z/4YE8jroEW Interestingly (but not surprisingly) you get different results depending on the optimization level.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.