D - Feature request? - virtual variables
- anderson (23/23) Mar 04 2003 Does D support virtual variables?
- anderson (8/31) Mar 05 2003 car getCar()
- Norbert Nemec (16/61) Mar 05 2003 That gives you a fundamental problem:
- anderson (22/83) Mar 06 2003 Did you mean?
- Norbert Nemec (26/26) Mar 07 2003 Sorry, my example really was an absolute mess. Should have taken a littl...
Does D support virtual variables? By this I mean, can variables be coverted to some sub-type variable. ie class A { car X; void turnOnCar() { X.run(); } X getCar() { return X; } } class B { holden X; // X is coverted to type holden } If the above breaks existing code, then you could always use the keyword virtual. I suppose pointers could be used for this ability, but they are more messy and less effecient. I think it would be useful for things like an extendable enumeration class .
Mar 04 2003
"anderson" <anderson badmama.com.au> wrote in message news:b43mjt$10r0$1 digitaldaemon.com...Does D support virtual variables? By this I mean, can variables be coverted to some sub-type variable. ie class A { car X; void turnOnCar() { X.run(); } X getCar() { return X; } }car getCar() { return X; } whoops.class B { holden X; // X is coverted to type holden } If the above breaks existing code, then you could always use the keyword virtual. I suppose pointers could be used for this ability, but they are more messy and less effecient. I think it would be useful for things like an extendable enumeration class.
Mar 05 2003
That gives you a fundamental problem: main { B special = new B; A general = A; car mycar = new car; A.X = mycar; holden myholden = B.X; // The object created as car has become a holden!!!!!!! }; The problem is inherent to the concept you are proposing. A variable type always is a input parameter (of the writer) and a output parameter (of the reader) so you can never change its type in a subclass without breaking the interface of the parent class. Ciao, Nobbi anderson wrote:"anderson" <anderson badmama.com.au> wrote in message news:b43mjt$10r0$1 digitaldaemon.com...Does D support virtual variables? By this I mean, can variables be coverted to some sub-type variable. ie class A { car X; void turnOnCar() { X.run(); } X getCar() { return X; } }car getCar() { return X; } whoops.class B { holden X; // X is coverted to type holden } If the above breaks existing code, then you could always use the keyword virtual. I suppose pointers could be used for this ability, but they are more messy and less effecient. I think it would be useful for things like an extendable enumeration class.
Mar 05 2003
"Norbert Nemec" <nobbi_at_theorie3.physik.uni-erlangen.de NOSPAM.COM> wrote in message news:b4592g$1trq$1 digitaldaemon.com...That gives you a fundamental problem: main { B special = new B; A general = A; car mycar = new car; A.X = mycar;Did you mean? general.X = mycar;holden myholden = B.X;Did you mean? holden myholden = special.X;// The object created as car has become a holden!!!!!!!If so I can't see why that should be in this case.}; The problem is inherent to the concept you are proposing. A variable type always is a input parameter (of the writer) and a output parameter (of the reader) so you can never change its type in a subclass without breaking the interface of the parent class.I'm probably just dumb, but I can't see what your talking about here. Holden should be a sub class of car, therefore all operations that apply to car should also work on holden. If car is being assigned to a holden such as X. A carH; B holdH; car mycar = new car; carH.X = mycar; holdH.X = mycar; //It should be in error. It'd be up to the programmer of A, to make sure this can never happen. Otherwise a copy constructor (in holden) could be used. The reader, can just perform a standard cast. Parhaps as I said before, the variable should be marked as virtual.Ciao, Nobbi anderson wrote:keyword"anderson" <anderson badmama.com.au> wrote in message news:b43mjt$10r0$1 digitaldaemon.com...Does D support virtual variables? By this I mean, can variables be coverted to some sub-type variable. ie class A { car X; void turnOnCar() { X.run(); } X getCar() { return X; } }car getCar() { return X; } whoops.class B { holden X; // X is coverted to type holden } If the above breaks existing code, then you could always use thearevirtual. I suppose pointers could be used for this ability, but theymore messy and less effecient. I think it would be useful for things like an extendable enumeration class.
Mar 06 2003
Sorry, my example really was an absolute mess. Should have taken a little more time for that... You are right, the corrected code (using your names) would be: main { B holdenH = new B; A carH = holdenH; // (1) car mycar = new car; carH.X = mycar; holden myholden = holdenH.X; // The object created as car has become a holden!!!!!!! }; My fundamental error really was in line (1) - see the corrected version above. The point is: Since B is a subclass of A, any object of type B must comply with the complete interface of A. carH actually is a reference to a object of type B, but since it looks like a "A", it will have to swallow any car that it thrown at it and save it in X. B can't claim to be "A and more" if it doesn't have the capability to swallow ordinary cars. Of course this all only applies if X is a public variable. But then - with private stuff you won't need that feature anyway, since you could just as well define a new variable "holden Y" and rewrite all routines that used X to use Y instead. (Maybe a little messy, but in a clean design, you'll need it rarely anyway.) Hope that made it a little clearer? Ciao, Nobbi
Mar 07 2003
"Norbert Nemec" <nobbi_at_theorie3.physik.uni-erlangen.de NOSPAM.COM> wrote in message news:b49rh5$1m08$1 digitaldaemon.com...Sorry, my example really was an absolute mess. Should have taken a little more time for that... You are right, the corrected code (using your names) would be: main { B holdenH = new B; A carH = holdenH; // (1) car mycar = new car; carH.X = mycar; holden myholden = holdenH.X;If you really wanted this ability, you'd probably create a copy constructor to covert a car to a holden. Or virtual variables could be treated as pointers that are initilized to the right type. Or make it an error.// The object created as car has become a holden!!!!!!! }; My fundamental error really was in line (1) - see the corrected version above. The point is: Since B is a subclass of A, any object of type B must comply with the complete interface of A. carH actually is a reference to a object of type B, but since it looks like a "A", it will have to swallow any car that it thrown at it and save it in X. B can't claim to be "A and more" if it doesn't have the capability to swallow ordinary cars. Of course this all only applies if X is a public variable. But then - with private stuff you won't need that feature anyway, since you could just as well define a new variable "holden Y" and rewrite all routines that used X to use Y instead. (Maybe a little messy, but in a clean design, you'llneedit rarely anyway.)Well, I was going to make it protected, but decided that this could also be done publicly (if need) with a few changes. The problem with redefining, is that you need (as you said) to rewrite all the routines and there's extra memory considerations. If you've derived 10 or 20 classes from the base class the cost of that can really add up. Generally I use a pointer to solve this problem which is cleaner then re-writting the the code every time, but not as clean as the method I suggest. It's kinda like a polymorphic way of templating. For example something like, class Error { Error1, Error2, Error3 } class Error2 : Error { Error4, Error5, } class A { virtual Error X; //Only need to write this once (in a real example there would be many other methods that use X) Error1 getErrors() { return X; } } class B : A { virtual Error2 X; } Anyway thanks for your explaination.Hope that made it a little clearer? Ciao, Nobbi
Mar 07 2003
"anderson" <anderson badmama.com.au> wrote in message news:b4a3ia$1ps1$1 digitaldaemon.com..."Norbert Nemec" <nobbi_at_theorie3.physik.uni-erlangen.de NOSPAM.COM>wrotein message news:b49rh5$1m08$1 digitaldaemon.com...littleSorry, my example really was an absolute mess. Should have taken aconstructormore time for that... You are right, the corrected code (using your names) would be: main { B holdenH = new B; A carH = holdenH; // (1) car mycar = new car; carH.X = mycar; holden myholden = holdenH.X;If you really wanted this ability, you'd probably create a copyto covert a car to a holden. Or virtual variables could be treated as pointers that are initilized to the right type. Or make it an error.type// The object created as car has become a holden!!!!!!! }; My fundamental error really was in line (1) - see the corrected version above. The point is: Since B is a subclass of A, any object of type B must comply with the complete interface of A. carH actually is a reference to a object ofitB, but since it looks like a "A", it will have to swallow any car thatwiththrown at it and save it in X. B can't claim to be "A and more" if it doesn't have the capability to swallow ordinary cars. Of course this all only applies if X is a public variable. But then -asprivate stuff you won't need that feature anyway, since you could justXwell define a new variable "holden Y" and rewrite all routines that usedbeto use Y instead. (Maybe a little messy, but in a clean design, you'llneedit rarely anyway.)Well, I was going to make it protected, but decided that this could alsodone publicly (if need) with a few changes. The problem with redefining, is that you need (as you said) to rewrite all the routines and there's extra memory considerations. If you've derived10or 20 classes from the base class the cost of that can really add up. Generally I use a pointer to solve this problem which is cleaner then re-writting the the code every time, but not as clean as the method I suggest. It's kinda like a polymorphic way of templating. For example something like, class Error { Error1, Error2, Error3 }class Error { e Error1; e Error2; e Error3; }class Error2 : Error { Error4, Error5, }class Error2 : Error { e Error4; e Error5; }class A { virtual Error X; //Only need to write this once (in a real example there would be manyothermethods that use X) Error1 getErrors() { return X; } } class B : A { virtual Error2 X; } Anyway thanks for your explaination.Hope that made it a little clearer? Ciao, Nobbi
Mar 07 2003