Logical const in D

前端 未结 5 1424
情书的邮戳
情书的邮戳 2020-12-06 16:54

D has two types of constness: immutable variables are ones that were declared immutable, and always will be immutable, while const variables are simply rea

5条回答
  •  [愿得一人]
    2020-12-06 17:46

    To mimic logical const from C++ in D you can use inheritance for classes:

    class ConstMatrix
    {
    public:
        double det() { // not marked as const!
            /* ... caching code ... */
        }
        /* ... the rest of the logically const interface ... */
    }
    
    class Matrix : ConstMatrix
    {
    public:
        void set( int row, int col, double val ) {
            /* ... */
        }
        /* ... the non-logically const interface ... */
    }
    

    In the ConstMatrix class implementation you won't have any compiler checks unless you put const qualifiers onto the function signatures. However, you will get const correctness for client code, if you use ConstMatrix for logically constant matrices.

    For structs you can use the alias technique to accomplish the same:

    struct ConstMatrix 
    {
        /* logically const bla bla blub */
    }
    
    struct Matrix
    {
    public:
        alias m this;
    
        /* non-const bla bla blub */
    private:
        ConstMatrix m;
    }
    

    For class types you can build other classes or structs with logical const correctness in the following way:

    class ConstBiggerClass
    {
    private:
        ConstMatrix m;
    }
    
    class BiggerClass : ConstBiggerClass
    {
    private:
        Matrix m;
    }
    

    This way the compiler will check const correctness for you. However, you'll need an extra data member. For class type members in class types, an alternative would be to provide a member function which returns the data member with the right constness:

    class ConstBiggerClass
    {
    public:
        void someLogicallyConstFunction( /*...*/ ) { /* ... */ }
    protected:
        abstract ConstMatrix getMatrix();
    }
    
    class BiggerClass : ConstBiggerClass
    {
    public:
        void someMutableFunction( /*...*/ ) { /*...*/ }
    protected:
        Matrix getMatrix() { return m; }
    private:
        Matrix m;
    }
    

提交回复
热议问题