invariant/const class storage class
Steven Schveighoffer
schveiguy at yahoo.com
Wed Oct 1 10:38:17 PDT 2008
The different methods of making a class instance invariant basically depend
on when the invariance applies. For classes where the type is declared
invariant, the invariant label is enforced after the memory is acquired and
initialized, and before the constructor is called. This doesn't seem to me
to be a very useful construct.
Casting after the class is created makes the invariant label apply after the
user has received the constructed class, but casting to invariant is up to
the user.
BTW, casting to invariant is the only possible way to make useful invariant
heap data. One generates the data, then casts it to invariant. Usually
this is done with brand-new memory so there is no chance for some separate
mutable reference to be formed. The downside is that the assurance that the
data is truly invariant is up to the developer. The compiler has to take
your word for it.
The proposed invariant constructors as defined in Andrei's functional
document (don't have the pdf link handy, but it's on the digitalmars web
site), I believe they had a section of code that you could set data, but
once you started using the 'this' pointer as arguments to other functions,
'this' implicitly switched to invariant. I believe this would make
invariant classes much more useful.
There is another alternative that works today. A public static method that
does this explicitly. If you make the constructor private, then you can
force the caller to use the public static method. e.g.:
class X
{
private this() {}
public static invariant(X) makeInstance() { return cast(invariant(X)) new
X();}
}
Now you can be assured that all instances of X are invariant, and you are
free to assign data to members in the constructor, making X a useful
construct. It's slightly better than fully custom invariance (such as with
Java Strings) in that the compiler and users of the class can make more
assumptions, and not as much care needs to be taken in implementing such a
class.
-Steve
"Nicolas Sicard" wrote
Yigal Chripun a écrit :
> I understand casting as breaking the type system. shouldn't there be a
> way to create invariant objects without the cast?
> an invariant constructor seems a good way to solve this. any plans on
> adding such a feature to D2?
>
> I think it can work like this:
>
> class A {
> this(params) {} // [1]
> invariant this(params) {} // [2]
> }
>
> // create a mutable object - will use type [1] c-tors.
> auto a = new A(params);
>
> // create an invariant object - will use type [2] c-tors.
> invariant a = new A(params);
>
> // create a const object - will use type [1] or [2] c-tors.
> const a = new A(params);
>
> in the const case, if there are two c-tors which only differ by
> invariant-ness of the c-tor using either will create ambiguity and
> therefore should be a compile-time error.
>
What should an invariant constructor do that a plain one don't, apart
from specifying immutability of the instance?
This would mean you could create instances of different types from the
same class, which is also kind of breaking the type system, isn't it?
But declaring a class invariant (for all instances) is something
interesting.
More information about the Digitalmars-d
mailing list