class-design – 如何重写在D中使用mutable的C代码?

前端之家收集整理的这篇文章主要介绍了class-design – 如何重写在D中使用mutable的C代码?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
如果你需要在D中重写以下C代码,你会怎么做?
struct A{

    const S* _s;
    B _b;
    C _c;
    mutable C _c1,_c2;

    A(const B& b,const C& c,const S* s){ /*...*/ }

    void compute(const R& r) const
    {
      //...
      _c1 = ...
      _c2 = ...
    }
};

D没有可变性,根据我的经验,它很少用于C语言.但是,假设在这里使用mutable是正确的原因,我在D中的选择是什么?

解决方法

您有三种方法可以解决这个问题:

>抛弃常数.这会使编译器起作用,但无法保证您的代码能够按预期工作.特别是,如果从多个线程在同一个对象上调用函数,那么您将受到数据竞争的支配.
>使用外部数据结构来存储可变对象:

struct A
{
    static C[const(A)*] _c1s,_c2s;

    void compute(ref const(R) r) const
    {
        _c1s[&this] = ...
        _c2s[&this] = ...
    }
}

我正在使用& this作为外部哈希表的关键,但你可能最好使用某种独特的ID.这是一个非常丑陋和棘手的解决方案.我不喜欢它.另请注意,哈希表是线程本地的,因此同一对象在不同的​​线程上将具有不同的值.这可能适用于您的特定应用,也可能不适用.
>重新思考如何在D中使用const

在D中,const是传递的和按位的,即不支持逻辑const.这样做的目的是保证不会出现并发共享数据写入.尽管你的代码在逻辑上可能是正确的,但如果两个线程试图在同一个对象上调用compute,它仍然会中断,因此D不允许它并且不提供合法的转义(不可变).

实质上,只有当它们是按位const时才应将函数标记为const.

结果是你应该在D中使用const比在C中少得多,因为你需要比你需要逻辑const少得多的按位const.

举个例子,考虑一个简单的(无意义的)泛型相等函数,告诉你两个对象是否相等:

bool equal(T)(T lhs,T rhs) { return lhs == rhs; }

请注意,我没有将函数参数标记为const.这是故意的.对相等性的测试不应该要求按位const – 它只需要逻辑const,因此在对象上强制执行D的const级别将是不必要的限制.

正如jA_cOp所说,D社区在D中看不到逻辑const的余地,无论好坏.当你尝试像C的const一样使用D的const时会出现问题.它们不一样,所以不要以同样的方式使用它们!如果函数可能需要使用逻辑const,那么就不要将它们标记为按位const!

猜你在找的C&C++相关文章