How to implement a null object?

More details

Here I found some information about the null object template ( https://softwareengineering.stackexchange.com/questions/152094/null-pointers-vs-null-object-pattern ) and here ( http://en.wikipedia.org/wiki /Null_Object_pattern#C.2B.2B ).

However, the C ++ implementation does not illustrate my use case.

I also saw a related link for the Nullable Type ( http://en.wikipedia.org/wiki/Nullable_type ).

Use case

I have an object that is not part of the hierarchy and usually does not stand out on the heap. In addition, there is no convenient value that can be used as a control unit to indicate a zero value. Hopefully the following code makes it easier to use.

class ContrivedType { public: ContrivedType() : mValue(0) { // Do nothing } bool operator==(const ContrivedType& other) const { return mValue == other.mValue; } void setValue(std::uint16_t value) { mValue = value; } private: // All values in the range [0, 65535] are valid for use std::uint16_t mValue; }; class Foo { public: const ContrivedType getValue() const { return mValue; } void setValue(const ContrivedType &value) { mValue = value; } private: ContrivedType mValue; }; int main() { Foo f; if (f.getValue() == ContrivedType()) { // Ambiguous case // - Was this value explicitly set to be the same value // as when it default constructed // OR // - Was the value never set } return 0; } 

Possible Solution 1

ContrivedType users to resolve due to default state and not use pointers to dynamically allocate ContrivedType . Perhaps something like this?

 class Foo { public: Foo() : mValue(nullptr) { // Do nothing } const ContrivedType* getValue() const { return mValue.get(); } void setValue(const ContrivedType &value) { if (!mValue) { mValue.reset(new ContrivedType(value)); } else { *mValue = value; } } private: std::unique_ptr<ContrivedType> mValue; }; 

It is now very clear whether the ContrivedType parameter is ContrivedType or not.

Possible Solution 2

Update the implementation of ContrivedType to support the null concept.

 class ContrivedType { public: ContrivedType() : mState(nullptr) { // Do nothing } explicit ContrivedType(std::uint16_t value) : mState(&mStorage) { mStorage.mValue = value; } bool isNull() const { return mState == nullptr; } bool operator==(const ContrivedType& other) const { if (!isNull()) { return mStorage.mValue == other.mStorage.mValue; } else { return other.isNull(); } } void setValue(std::uint16_t value) { mStorage.mValue = value; if (!mState) { mState = &mStorage; } } private: struct State { // All values in the range [0, 65535] are valid for use std::uint16_t mValue; }; State mStorage; // This will point to the storage when a value actually set State* mState; }; 

Question

Is there an established scheme or idiom for this concept? If there are no recommendations for its implementation?

Justification

In real code, there are classes with 1 or more members that are optional in some contexts. These classes are serialized over the socket using a protocol that supports missing fields (for example, optional fields). Instead of spending bytes on serializing a default built object that was not explicitly set, serialization might skip optional fields. For example, the function updateFoo(const Foo&) . If only a subset of an existing Foo instance is updated, then only those fields should be serialized.

Edit

It looks like std::experimental::optional (brought to my attention by @myaut) is what I would like to use, but I don't have access to it.

At this point, I will need to use a solution that will work with Visual Studio 2013 (probably 2015) and g ++ 4.8.

+6
source share
1 answer

From this question (think about this;):

std::experimental::optional is taken from Boost.Optional , and this implementation works well in Visual C ++ 12.0 (although it differs slightly ). A single heading reference implementation based on document N3793 can be found here .

The latest list of supported kernel functions and the C ++ 11/14 / 1z library that ships with Visual Studio can be found in the Visual C ++ Team blog , from this post in particular. The set of header files for implementing the standard library (and some extensions) from Microsoft can be viewed here .

I had a taste lately, with little effort to create it, I managed to use it and was pleased with it. Hope this helps.

+2
source

Source: https://habr.com/ru/post/984710/


All Articles