c++ - 如何实现空对象?

标签 c++

详情

我在这里 ( https://softwareengineering.stackexchange.com/questions/152094/null-pointers-vs-null-object-pattern ) 和这里 ( http://en.wikipedia.org/wiki/Null_Object_pattern#C.2B.2B) 找到了一些关于空对象模式的信息。

但是,C++ 实现并未说明我的用例。

我还看到了可空类型 ( http://en.wikipedia.org/wiki/Nullable_type ) 的相关链接。

用例

我有一个不属于层次结构的对象,通常不会在堆上分配。此外,没有一个方便的值可以用作标记来指示 null。希望以下代码使用例清晰。

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's default constructed
        // OR
        // -    Was the value never set
    }

    return 0;
}

可能的解决方案1

强制需要区分默认状态和unset 之间歧义的ContrivedType 用户使用指针并动态分配ContrivedType。也许是这样的?

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;
};

现在很清楚是否设置了ContrivedType

可能的解决方案2

更新 ContrivedType 的实现以支持 null 的概念。

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;
};

问题

这个概念是否有既定的模式或惯用语?如果没有,是否有任何实现建议?

理由

在实际代码中,有些类具有 1 个或多个成员,它们在某些情况下是可选的。这些类正在使用支持缺失字段(即可选字段)的协议(protocol)通过套接字进行序列化。序列化可以跳过可选 字段,而不是浪费字节序列化未显式设置的默认构造对象。例如,updateFoo(const Foo&) 函数。如果只有现有 Foo 实例的一个子集被更新,那么只有那些字段需要被序列化。

编辑

看起来 std::experimental::optional(@myaut 引起了我的注意)是我想要使用的,但我无权访问它。

现在我需要使用适用于 Visual Studio 2013(2015 可能没问题)和 g++ 4.8 的解决方案。

最佳答案

来自 this question (想赞成它;):

std::experimental::optional originates from the Boost.Optional library, and this implementation works well in Visual C++ 12.0 (though it differs a little). Reference single-header implementation, based on the N3793 proposal paper, can be found here.

The latest list of supported C++11/14/1z core and library features that are shipped with Visual Studio can be found from the Visual C++ Team blog, from this post in particular. A set of header files of the Standard Library implementation (and some extensions) from Microsoft can be viewed here.

我最近尝试了一下,为了构建它付出了一些努力,我设法使用了它并且对它很满意。希望对您有所帮助。

关于c++ - 如何实现空对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29460651/

相关文章:

c++ - 自动生成的 WAF 解决方案加载失败

c++ - C++ 中的位数组

C++语法问题

c++ - 优化 SphereInFrustrum 检查

c++ - 如何在 Visual Studio 中更改访问修饰符后的代码缩进

c++ - 我将如何实现这种蛮力中值搜索算法?

c++ - 键入循环时如何修复 visual studio 自动完成?

c++ - 2个函数中的不同条件锁定

c++ - 具有包含另一个类的函数指针的映射的类

c++ - 什么是 "symbolic constants"和 "magic constants"?