简体   繁体   中英

Is there a rule of thumb to decide where to store my classes (i.e. what type of memory)?

Suppose I have a c++ program which with several classes which are related like this:



    class Application
    {
    public:
      // some functions
    private:
      BusinessLogic businessLogic;
      // some variables 
    };
    
    class BusinessLogic
    {
    public:
      // some functions
    private:
      BusinessLogicSubClass1 businessLogicSubClass1; 
      BusinessLogicSubClass2 businessLogicSubClass2;
      // some other member variables 
    };
    
    BusinessLogicSubClass1 
    {
    public:
      // some functions
    private:
      SubClassOfSubClass1 subClassOfSubClass1; 
      // some other member variables 
    };
    
    // etc.... (you get the idea I hope)

The point is, I know at compile time that there is an Application class that contains the BusinessLogic class which contains many sub classes. I also know that I only need one instance of the Application class. Now the question is how to decide on where to store such a class in memory?

As far as I know there are three main possibilities:

  1. on the stack:


    int main()
    {
      Application application();
      // do something with application
      return 0;
    }

  1. on the heap:


    int main()
    {
      std::unique_ptr application = std::make_unique&ltApplication>();
      // do something with application
      return 0;
    }

  1. as a static:


    int main()
    {
      static Application application();
      // do something with application
      return 0;
    }

I read some information on the different types of memory. Based on what I read, I think it is not the best decision to store the application class on the stack. Mainly because the stack has a limited size and there is a very limited advantage of having the stack's automatic memory management (ie cleaning up variables that go out of scope) in this case.

I find it harder to decide however how to make the trade of between static and heap memory. In the simplified example above I think I go with static, because everything is known at compile time and static memory is said to be more efficient, compared to heap memory. (Does this way of thinking make any sense, or am I overlooking something here?)

However, there are some examples in which the choice becomes less evident. Suppose the application needs to be initialized via an.ini file. If you store the instance of the Application class on the heap, it will be possible to pass the initialization values via the constructor:



    int main
    {
      IniFileReader reader;
      InitializationValues iniValues = reader.GetIniValues(); 
      std::unique_ptr application = std::make_unique&ltApplication2>(iniValues);
      // do something with application
      return 0;
    }

As far as I know, constructor initialization is considered to be better in terms of design than using some Init function like this:



    int main
    {
      static Application3 application();
      IniFileReader reader;
      InitializationValues iniValues = reader.GetIniValues(); 
      application.Init(iniValues);
      // do something with application
      return 0;
    }

So here the choice is between cleaner code or a more efficient program. I realize this is sort of trade off is very much dependent on what type of application you intend to build.

What I am looking for is, if there are perhaps some rules of thumb or a sort of flow chart to decide where to store your classes?

Some (not necessarily good) examples of such rules could be:

  • if you know everything about a class at compile time and you know there is only one instance, try to always store it as a static.
  • always use the heap for objects that are shared between different threads.
  • it does not really matter in this or that case, so chose for cleaner code.

And secondly, are there any general guidelines or design principles on where to put the static classes? I find it hard to decide where to put a static class if they need to be accessed by more than one other class. Globals are generally considered bad design for instance.

A practical example of such a dilemma, can be found in the following article on the state design pattern: https://gameprogrammingpatterns.com/state.html --> see subsection static states

I am not sure if the authors choice to put a static instance of each state in the base class is the best design. He also admits to put them there "for no particular reason". Any suggestions for a better place? Make a sort of state-database class? Make a singleton of each state?

One very common way to handle your situation is to use a Singleton design pattern. you can find lots of good references on stack overflow, or via a simple google search. Take a look at this one for example. For you it would look something like this:

class Application
{
    public:
        static Application& getInstance()
        {
            static Application instance;
            return instance;
        }
    private:
        Application() {}
    ...
};

For dynamic parameters, I'm not sure I would agree that it's always better to initialize in the constructor, but the details really matter for this. There are cases where it does make sense, and cases where it doesn't. In the singleton case you almost always need some sort of separate "Init" call since you don't want to pass construction arguments on every call to getInstance() .

To your question about "heap" versus "static". Assuming you really are only creating one Application instance, and you're running on a "desktop" OS like Linux/Window/MacOS, there will be no meaningful difference between these two. Uninitialized static variables are usually placed in .bss , and the first thing the OS will do when launching your process is dynamically allocate a bunch of pages to make space for the various data sections in your program. Not a whole lot different from what you're doing in code (ie a one-time dynamic memory allocation).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM