What (not) to do in a constructor

后端 未结 13 1660
悲&欢浪女
悲&欢浪女 2020-12-12 17:33

I want to ask you for your best practices regarding constructors in C++. I am not quite sure what I should do in a constructor and what not.

Should I only use it for

相关标签:
13条回答
  • 2020-12-12 17:53

    I think the most important thing is a bit of common sense! There's lots of talk about do's and dont's - all well and good, but the key point to consider is how your object will be used. For example,

    1. how many instances of this object will be created? (are they held in containers for example?)
    2. how often are they created and destroyed? (loops?)
    3. how big is it?

    If this object is a single instance, that is constructed at the start and the construction is not in the critical path - why not do the heavy work in the constructor (as long as you use exceptions appropriately, it may even make more sense)? If on the other hand, it's a very light weight object that is created and destroyed in a loop for a short period of time - try do as little as possible (aside from initializing the members, for example) (functors are a very good example of this...)

    There are advantages to having a two phase load (or whatever), but main disadvantage is forgetting to call it - how many of us have done that?? :)

    So, my tuppence is, don't stick to a hard and fast rule, look carefully at how your object is to be used, and then design it to suit!

    0 讨论(0)
  • 2020-12-12 17:54

    Simple answer: it depends.

    When designing your software you should might want to program via the RAII principle ("Resource Acquisition is initialization"). This means (among other things) that the object itself is responsible for its resources, and not the caller. Also, you might want to familiarize yourself with exception safety (in their different degrees).

    For example, consider:

    void func() {
        MyFile f("myfile.dat");
        doSomething(f);
    }
    

    If you design the class MyFile in the way, that you can be sure before doSomething(f) that f is initialized, you save a lot of trouble checking for that. Also, if you release the ressources held by f in the destructor, i.e. close the file handle, you are on the safe side and it is easy to use.

    In this specific case you can use the special properties of constructors:

    • If you throw an exception from the constructor to its outside world, the object will not be created. This means, the destructor will not be called and the memory will be freed immediately.
    • A constructor must be called. You can not force the user to use any other function (except the destructor), only by convention. So, if you want to force the user to initialize your object, why not via the constructor?
    • If you have any virtual methods, you should not call those from inside the constructor, unless you know what you are doing -- you (or later users) might get surprised why the virtual overriding method is not called. Best not to confuse anyone.

    A constructor must leave your object in a usable state. And because it is aways wise to make it difficult to use your API wrong, the best thing to do is make it easy to be used correct (sic to Scott Meyers). Doing initialization inside the constructor should be your default strategy -- but there are always exceptions, of course.

    So: It is a good way to use constructors for initialization. It is not always possible, for example GUI frameworks often need to be constructed, then initialized. But if you design your software completely in this direction, you can save a lot of trouble.

    0 讨论(0)
  • 2020-12-12 17:55

    A constructor is used to construct an object - nothing more and nothing less. You need to do whatever it takes to establish the class invariants within a constructor and how complex that is it really depends on the type of the object being initialized.

    Separate init() functions are a good idea only if for some reason you can't use exceptions.

    0 讨论(0)
  • 2020-12-12 17:59

    You can do what you want to do, but use constructor for that purpose for what it's call - create object. and if for that need to call others methods, that's Ok. just follow one rule - don't make it complex more than it's need. Good practice is to do constructor as simple as possible, but that not means that you need just initialize members.

    0 讨论(0)
  • 2020-12-12 18:00

    Well, «constructor» comes from construction, building, setting up. So there's where all initialization happens. Whenever you instance a class, use the constructor to ensure that everything is done in order to make the new object workable with.

    0 讨论(0)
  • 2020-12-12 18:04

    A constructor is expected to create an object that can be used from the word go. If for some reason it is not able to create a usable object, it should throw an exception and be done with it. So, all supplementary methods/functions that are necessary for an object to work properly should be called from the constructor (unless you want to have lazy-loading like features)

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