lundi 2 décembre 2019

Pattern for removing default constructor which leaves data in "bad state"?

Let's say you have a class which have members which should always be set (i.e. defaults would leave it in a bad state). To prevent having objects with "bad state", you have a constructor which requires everything to be set. The issue is, that you also have a set of "factory" classes, create the objects by parsing some data stream and setting members directly. You want to be explicit about which classes can construct your objects without using the constructor. Is there a good pattern for this?

Example:

enum class DataState
{
     STATE_ONE,
     STATE_TWO
};

class Data
{
public:
   Data(std::string _dp1, DataState _dp2): dp1(_dp1), dp2(_dp2) {}
   Data() {}; /* Don't want this constructor because it forces a default for dp2

   std::string dp1;
   DataState dp2;
};

The default constructor is needed because you have factory classes which get callbacks with a "Data" object, and fill it's members on a per member basis. .i.e. something like:

Field1Callback(Data &d, const std::string &fieldVal)
{
    d.dp1 = field;
}

Field2Callback(Data &d, const std:string &fieldVal)
{
    d.dp2 = ConvertToState(fieldVal);
}

Are there any patterns for being explicit about what classes are allowed to call "default" constructors? i.e. serializers and parsers?

Aucun commentaire:

Enregistrer un commentaire