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
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 class
es or struct
s 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;
}