Ctor, setters and invariant
Simen Kjærås
simen.kjaras at gmail.com
Sat Mar 2 12:05:03 PST 2013
On Sat, 02 Mar 2013 11:02:08 +0100, simendsjo <simendsjo at gmail.com> wrote:
> invariant is called when a method enters. This creates problems if the
> constructor calls a setter:
>
> import std.exception;
> struct S {
> private int _i;
> public:
> this(int i) {
> this.i = i;
> }
> @property void i(int v) {
> enforce(v > 1);
> _i = v;
> }
> invariant() {
> assert(_i > 1);
> }
> }
> unittest {
> S(10);
> }
> void main() {}
>
>
> In this example, invariant is called at the start if the property i
> called through the constructor. Calling setters in constructors is
> sometimes a good way to make sure everything is initialized properly,
> but as invariant is called, this becomes impossible.
>
> Is it possible that invariant() is only called at the end of ctor
> instead of at the beginning and end of each setter when called from the
> ctor? The ctor will often have the object in an invalid state while
> constructing the object, so calling invariant() while in ctor will
> almost always create problems.
>
> Or does anyone know a better way to solve this that doesn't require code
> duplication?
import std.exception;
struct S {
private int _i;
private bool inConstructor = true;
public:
this(int i) {
this.i = i;
this.inConstructor = false;
}
@property void i(int v) {
enforce(v > 1);
_i = v;
}
invariant() {
if (inConstructor) return;
assert(_i > 1);
}
}
unittest {
S(10);
}
void main() {}
Not perfect, but it works.
--
Simen
More information about the Digitalmars-d-learn
mailing list