How much work should be done in a constructor?

后端 未结 18 968
离开以前
离开以前 2020-11-27 17:40

Should operations that could take some time be performed in a constructor or should the object be constructed and then initialised later.

For example when constructi

相关标签:
18条回答
  • 2020-11-27 17:49

    RAII is the backbone of C++ resource management, so acquire the resources you need in the constructor, release them in the destructor.

    This is when you establish your class invariants. If it takes time, it takes time. The fewer "if X exists do Y" constructs you have, the simpler the rest of the class will be to design. Later, if profiling shows this to be a problem, consider optimizations like lazy initialization (acquiring resources when you first need them).

    0 讨论(0)
  • 2020-11-27 17:50

    The most important jobs of a constructor is to give the object an initial valid state. The most important expectation on the constructor, in my opinion, is that the constructor should have NO SIDE EFFECTS.

    0 讨论(0)
  • 2020-11-27 17:52

    You usually do not want the constructor to do any computation. Someone else using the code will not expect that it does more than basic set-up.

    For a directory tree like you're talking about, the "elegant" solution is probably not to build a full tree when the object is constructed. Instead, build it on demand. Someone using your object may not really care what is in sub-directories, so start out by just having your constructor list the first level, and then if someone wants to descend into a specific directory, then build that portion of the tree when they request it.

    0 讨论(0)
  • 2020-11-27 17:52

    Try to have what you think is necessary there and dont think about if it will be slow or fast. Preoptimization is a time waster so code it, profile it and optimize it if needed.

    0 讨论(0)
  • 2020-11-27 17:56

    As much as necessary and no more.

    The constructor must put the object into a usable state, hence at a minimum your class variables ought to be initted. What initted means can have a broad interpretation. Here is a contrived example. Imagine you have a class that has the responsibility of providing N! to your calling application.

    One way to implement it would be to have the constructor do nothing, with a member function with a loop that calculates the value needed and returns.

    Another way to implement it would be to have an class variable which is an array. The constructor would set all the values to -1, to indicate that the value has not been calculated yet. the member function would do lazy evaluation. It looks at the array element. If it is -1, it calculates it and stores it and returns the value, otherwise it just returns the value from the array.

    Another way to implement it would be just like the last one, only the constructor would precalculate the values, and populate the array, so the method, could just pull the value out of the array and return it.

    Another way to implement it would be to keep the values in a text file, and use N as the basis for an offset into the file to pull the value from. In this case, the constructor would open the file, and the destructor would close the file, while the method would do some sort of fseek/fread and return the value.

    Another way to implement it, would be to precompute the values, and store them as a static array that the class can reference. The constructor would have no work, and the method would reach into the array to get the value and return it. Multiple instances would share that array.

    That all being said, the thing to focus on, is that generally you want to be able to call the constructor once, then use the other methods frequently. If doing more work in the constructor means that your methods have less work to do, and run faster, then it is a good trade off. If you are constructing/destructing a lot, like in a loop, then it is probably not a good idea to have a high cost for your constructor.

    0 讨论(0)
  • 2020-11-27 17:57

    To summarize:

    • At a minimum, your constructor needs to get the object configured to the point that its invariants are true.

    • Your choice of invariants may affect your clients.(Does the object promise to be ready for access at all times? Or only only in certain states?) A constructor that takes care of all of the set-up up-front may make life simpler for the class's clients.

    • Long-running constructors are not inherently bad, but may be bad in some contexts.

    • For systems involving a user-interaction, long-running methods of any type may lead to poor responsiveness, and should be avoided.

    • Delaying computation until after the constructor may be an effective optimization; it may turn out to be unnecessary to perform all the work. This depends on the application, and shouldn't be determined prematurely.

    • Overall, it depends.

    0 讨论(0)
提交回复
热议问题