D - [Idea] Extendable properties
- J Anderson (16/16) Mar 18 2004 Parhaps something for 2.0.
- Matthew (5/21) Mar 18 2004 Haven't the faculties to really think about it at the mo, but it seems
- Jeroen van Bemmel (19/45) Mar 18 2004 The idea is not bad, although it somehow feels like a can of wurms. I'm ...
- Stephan Wienczny (11/16) Mar 18 2004 I think it is possible.
- Jeroen van Bemmel (10/26) Mar 18 2004 that
- J Anderson (5/25) Mar 18 2004 Good point, all of which also show the difficultly in doing something
- Russ Lewis (36/88) Mar 18 2004 How about this code which is ALMOST legal:
- J Anderson (10/45) Mar 18 2004 This is the kinda workaround I mentioned before that I don't like.
- J Anderson (38/42) Mar 18 2004 If the object is initialized (and I'm not suggesting that this should be...
Parhaps something for 2.0. class A {} class B : A { } class D { A a; } class E : D { a : B; //A is extended to b } It would be useful for creating things like static virtual methods and for changing properties in classes the user doesn't have control over. This would of course probably need to be extended for getters and setters as well. For course at the moment this can be simulated (and has been simulated) with a whole load of casting but that's not nice. -- -Anderson: http://badmama.com.au/~anderson/
Mar 18 2004
Haven't the faculties to really think about it at the mo, but it seems attractive. Maybe Ilya can point out some important flaws in it, or even that aren't. ;) "J Anderson" <REMOVEanderson badmama.com.au> wrote in message news:c3cs6c$1bls$1 digitaldaemon.com...Parhaps something for 2.0. class A {} class B : A { } class D { A a; } class E : D { a : B; //A is extended to b } It would be useful for creating things like static virtual methods and for changing properties in classes the user doesn't have control over. This would of course probably need to be extended for getters and setters as well. For course at the moment this can be simulated (and has been simulated) with a whole load of casting but that's not nice. -- -Anderson: http://badmama.com.au/~anderson/
Mar 18 2004
The idea is not bad, although it somehow feels like a can of wurms. I'm not quite sure why One potential issue is order of construction of objects. Class E in your example would need an allocating constructor that reserves enough memory for E, plus sizeof(B) memory for a. Then, normally, the base class D initializing constructor would be called, which initializes the 'A' part of a. Then, the extended 'B' part of a is initialized as part of E's constructor. The problem is, that for the latter partial construction of a, 'B' needs to have a separate constructor that initializes B member variables but does not call the baseclass constructor in A. This is needed for all derived classes that may potentially be used as extended properties, so each derived class now gets 3 different constructors: (1) allocating constructor, (2) initializing constructor, and (3) partial constructor. These could call each other, so (1) calls (2) which calls base.(2) followed by (3) Walter: in general you cannot call virtual methods from a constructor, right? Since otherwise you would be able to call a method on an object that is not properly initialized yet, eg when the D constructor would call D.virtualMethod() which is overridden in E"J Anderson" <REMOVEanderson badmama.com.au> wrote in message news:c3cs6c$1bls$1 digitaldaemon.com...Parhaps something for 2.0. class A {} class B : A { } class D { A a; } class E : D { a : B; //A is extended to b } It would be useful for creating things like static virtual methods and for changing properties in classes the user doesn't have control over. This would of course probably need to be extended for getters and setters as well. For course at the moment this can be simulated (and has been simulated) with a whole load of casting but that's not nice. -- -Anderson: http://badmama.com.au/~anderson/
Mar 18 2004
Jeroen van Bemmel wrote:Walter: in general you cannot call virtual methods from a constructor, right? Since otherwise you would be able to call a method on an object that is not properly initialized yet, eg when the D constructor would call D.virtualMethod() which is overridden in EI think it is possible. When you create an object d of a given class D, D's vtbl is copied into d.classinfo.vtbl. Then the constructor of the class you created is called. At this stage all member variables are already initialized using the types base value or its basic value (e.g. int a = 5). Then you can use 'super()' to call the base class constructors. If you call a virtual method before super() you shouldn't expect any initialisation in super class constructors ;-) Did I get your point? Stephan
Mar 18 2004
"Stephan Wienczny" <wienczny web.de> wrote in message news:c3dg4l$2evb$1 digitaldaemon.com...Jeroen van Bemmel wrote:thatWalter: in general you cannot call virtual methods from a constructor, right? Since otherwise you would be able to call a method on an objectI would expect that d gets a pointer to the vtbl in D, but okis not properly initialized yet, eg when the D constructor would call D.virtualMethod() which is overridden in EI think it is possible. When you create an object d of a given class D, D's vtbl is copied into d.classinfo.vtbl.Then the constructor of the class you created is called. At this stage all member variables are already initialized using the types base value or its basic value (e.g. int a = 5). Then you can use 'super()' to call the base class constructors. If you call a virtual method before super() you shouldn't expect any initialisation in super class constructors ;-) Did I get your point?Yes and no. This looks like a workaround, but a) is it enforced? it heavily depends on developer knowledge, and it's easy to make mistakes and get strange errors b) it's counter intuitive (eg C++ does it differently) In general, I would expect base class initialization to finish before subclass initialization.
Mar 18 2004
Jeroen van Bemmel wrote:The idea is not bad, although it somehow feels like a can of wurms. I'm not quite sure why One potential issue is order of construction of objects. Class E in your example would need an allocating constructor that reserves enough memory for E, plus sizeof(B) memory for a. Then, normally, the base class D initializing constructor would be called, which initializes the 'A' part of a. Then, the extended 'B' part of a is initialized as part of E's constructor. The problem is, that for the latter partial construction of a, 'B' needs to have a separate constructor that initializes B member variables but does not call the baseclass constructor in A. This is needed for all derived classes that may potentially be used as extended properties, so each derived class now gets 3 different constructors: (1) allocating constructor, (2) initializing constructor, and (3) partial constructor. These could call each other, so (1) calls (2) which calls base.(2) followed by (3) Walter: in general you cannot call virtual methods from a constructor, right? Since otherwise you would be able to call a method on an object that is not properly initialized yet, eg when the D constructor would call D.virtualMethod() which is overridden in EGood point, all of which also show the difficultly in doing something simular manually also. -- -Anderson: http://badmama.com.au/~anderson/
Mar 18 2004
How about this code which is ALMOST legal: class A {} class B : A {) class D { this(A a) in { assert(a !== null); assert(a); } body { this.a = a; } this() { this(new A); } A a; } class E : D { this() { super(new B); } B a() out(retval) { assert(ret !== null); assert(retval); } body { return cast(B)super.a; } } The problem, of course, is that the return value B from E.a() does not match the type of D.a. However, it seems to me that there is no reason why this should not be legal. Anybody who is interfacing to an E object through a reference of type D will be expecting that the D.a be of type A; certainly if we return an object of type B, we fulfill this requirement. People accessing the object through a reference of type E will know about the newer, more specific function, and will be able to make use of it. Jeroen van Bemmel wrote:The idea is not bad, although it somehow feels like a can of wurms. I'm not quite sure why One potential issue is order of construction of objects. Class E in your example would need an allocating constructor that reserves enough memory for E, plus sizeof(B) memory for a. Then, normally, the base class D initializing constructor would be called, which initializes the 'A' part of a. Then, the extended 'B' part of a is initialized as part of E's constructor. The problem is, that for the latter partial construction of a, 'B' needs to have a separate constructor that initializes B member variables but does not call the baseclass constructor in A. This is needed for all derived classes that may potentially be used as extended properties, so each derived class now gets 3 different constructors: (1) allocating constructor, (2) initializing constructor, and (3) partial constructor. These could call each other, so (1) calls (2) which calls base.(2) followed by (3) Walter: in general you cannot call virtual methods from a constructor, right? Since otherwise you would be able to call a method on an object that is not properly initialized yet, eg when the D constructor would call D.virtualMethod() which is overridden in E"J Anderson" <REMOVEanderson badmama.com.au> wrote in message news:c3cs6c$1bls$1 digitaldaemon.com...Parhaps something for 2.0. class A {} class B : A { } class D { A a; } class E : D { a : B; //A is extended to b } It would be useful for creating things like static virtual methods and for changing properties in classes the user doesn't have control over. This would of course probably need to be extended for getters and setters as well. For course at the moment this can be simulated (and has been simulated) with a whole load of casting but that's not nice. -- -Anderson: http://badmama.com.au/~anderson/
Mar 18 2004
Russ Lewis wrote:How about this code which is ALMOST legal: class A {} class B : A {) class D { this(A a) in { assert(a !== null); assert(a); } body { this.a = a; } this() { this(new A); } A a; } class E : D { this() { super(new B); } B a() out(retval) { assert(ret !== null); assert(retval); } body { return cast(B)super.a; } } The problem, of course, is that the return value B from E.a() does not match the type of D.a. However, it seems to me that there is no reason why this should not be legal. Anybody who is interfacing to an E object through a reference of type D will be expecting that the D.a be of type A; certainly if we return an object of type B, we fulfill this requirement. People accessing the object through a reference of type E will know about the newer, more specific function, and will be able to make use of it.This is the kinda workaround I mentioned before that I don't like. I still think a post-constructor would make life so much easier. 2 lines as opposed to 20 (although I'd say most of those asserts aren't absolutely nessary). This is pretty close to what I suggested anyway (ie support for getters and setters as well). The other problem with this is that the parent class has to be prepared. Consider you don't have access to the parent class. -- -Anderson: http://badmama.com.au/~anderson/
Mar 18 2004
Matthew wrote:Haven't the faculties to really think about it at the mo, but it seems attractive. Maybe Ilya can point out some important flaws in it, or even that aren't. ;)If the object is initialized (and I'm not suggesting that this should be allowed), what is the order? class A {} class B : A { } class D { A a = new A; } class E : D { a : B = new B; //??? - What to do here. } You'd end up with two constructions or B being constructed twice. Construction has to occur somewhere. I guess a something like a vtable could be used and variables for overload would be indicated. That way when construction occurs it would call the vtable function instead. class A {} class B : A { } class D { virtual A a = new A; //The constructor is looked up } class E : D { a : B = new B; //new B is called, not new A } It then would require another entry in the vtable but only one for construction of all virtual objects. The problem I see is that like in C++, programmers will not put virtual. Therefore the vtable thing may need to be mandatory :( Parhaps it could be optimised out some way? Of course if its always has to be null then the problem is moved else where (possibly the constructor -> which could be confusing to some users). Another way would be to have a special function for construction that is only called at the top level (this can be simulated). That would be useful for other things also. It would also easily be simulated by virtual method if a post construction function was available. -- -Anderson: http://badmama.com.au/~anderson/
Mar 18 2004