Brent212
Brent212

Reputation: 1874

C++: is there a better alternative to using static attributes for this case?

I have a "processor" class that requires a few things: 1) Access to an instance of a class that allows access to a database. 2) Access to a string utility class. 3) A timeout integer value that is read from a config file at runtime.

So I'd like to have pointers to the first two as member attributes and a simple int attribute for the third. Usually, in a case like this, I'd just have the constructor take pointers for the first two and an int for the third, and then in the body, assign the members to the passed in items.

The problem is that I'm going to have a pool of something like 100 instances of this processor class, and I'm wondering if it's a waste of memory to have each instance contain it's own (2) pointers and integer attribute, when all the pointers will be pointing to the same two objects and all the integers will hold the same value throughout the life of the process.

I'm familiar with the "global state is bad" concept and am under the impression that it discourages use of static member attributes. But in this case, wouldn't it be more efficient to simply have these three attributes be static? Then I'd just create a static "initStaticMembers" method that takes in the two pointers and the integer, and assigns the static member attributes to the passed in items. initStaticMembers would get called once before the pool of processor instances is created.

I'm not a huge fan of that last part (the static initStaticMembers method)... just doesn't seem very elegant, but I can't see a clearly better alternative. Anyone have a suggestion? And am I correct in thinking that using static attributes would save memory over giving each processor class instance it's own set of attribute instances?

I also should note that the classes being pointed to are thread safe, so I don't think I need to be concerned with all the processors sharing a single pointer to each of those.

Thanks for any feedback.

Upvotes: 0

Views: 872

Answers (2)

yzt
yzt

Reputation: 9113

Given the situation you've described, using static members would indeed save some memory (a very small amount in this case.)

And if you can guarantee two conditions, then I'd say that the use of statics here would be safe and sound. The two conditions are:

  1. initStaticMembers always gets called before any of these static member data is used;
  2. The lifetime of all Processor instances start after the lifetime of your database access class and your string utility class, and end before them.

If you can guarantee these (for example, in the code managing the pool of Processors) then you are fine. Just as a good coding practice, make sure you call initStaticMembers again after all the processors are done, with nullptr and zero values.

Avoiding static data is generally a very good practice. But that's mostly because you can't easily control the lifetime (and order of initialization) of static objects. However, it looks like your static pointer members don't actually own anything and don't control the lifetime of any objects, which is a good thing here.

So in short, if you are careful, using static member data in this case should be fine and OK. But, I need to emphasize again that you aren't saving much memory here.

If your static data were larger (larger than a couple of pointers and an int,) I would suggest using non-static shared_ptrs instead of raw pointers to point to them. However, in your case, the shared_ptr data structure will be larger than your whole shared data.

Upvotes: 1

paddy
paddy

Reputation: 63481

If the database class is truly an application-global thing, then make it global. Some things just are global, and fighting that will lead to code that is difficult to read.

When your application is self-contained, and the classes you are writing are specific to that application, it's often okay to utilize the Singleton Pattern to create an Application class.

Application::GetInstance().GetDatabase();

Where you have the static method:

Application& Application::GetInstance()
{
    static Application app;
    return app;
}

Upvotes: 0

Related Questions