Reputation: 1874
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
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:
initStaticMembers
always gets called before any of these static member data is used;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 Processor
s) 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_ptr
s 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
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