www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Find out most derived class in base class

reply Michal Minich <michal.minich gmail.com> writes:
How do I solve this, without parametrizing class.

class Base {
    void foo () { I want get somehow to type *Derived2* at CT }
}

class Derived1 : Base { }
class Derived2 : Base { }
Nov 19 2010
next sibling parent reply Michal Minich <michal.minich gmail.com> writes:
On Fri, 19 Nov 2010 20:50:13 +0000, Michal Minich wrote:

 How do I solve this, without parametrizing class.
 
 class Base {
     void foo () { I want get somehow to type *Derived2* at CT }
 }
 
 class Derived1 : Base { }
 class Derived2 : Base { }

By making mistake, I realized that it is not possible :) The last line should be: class Derived2 : Derived1 { } The *Base* has two most derived classes in the first example. Anyway, is it somehow possible to iterate derived classes if I only know base class? At CT.
Nov 19 2010
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 19 Nov 2010 15:54:08 -0500, Michal Minich  
<michal.minich gmail.com> wrote:

 On Fri, 19 Nov 2010 20:50:13 +0000, Michal Minich wrote:

 How do I solve this, without parametrizing class.

 class Base {
     void foo () { I want get somehow to type *Derived2* at CT }
 }

 class Derived1 : Base { }
 class Derived2 : Base { }

By making mistake, I realized that it is not possible :) The last line should be: class Derived2 : Derived1 { } The *Base* has two most derived classes in the first example. Anyway, is it somehow possible to iterate derived classes if I only know base class? At CT.

No. You don't know all the derived classes until link time, and there's no doing anything except linking at link time. You should be able to find out at runtime which classes are derived from Base. -Steve
Nov 19 2010
parent reply div0 <div0 sourceforge.net> writes:
On 19/11/2010 21:05, Jonathan M Davis wrote:
 On Friday 19 November 2010 12:56:38 Steven Schveighoffer wrote:

 And how would you know that at runtime? All reflection in D at this point is
 compile-time reflection, and that isn't going to help you any here (for the
very
 reasons that you list). I don't see how you could determine which classes are
 derived from a particular class at runtime. You could use typeof() to determine
 what the exact type of a reference is, but that wouldn't help you determine
what
 derived classes exist for a particular type. What you'd really need is runtime
 reflection, which D doesn't have.

 - Jonathan M Davis

How would dynamic cast work if you can't find out the inheriting classes from a reference? At runtime, the runtime type info for classes forms a DAG. As D only allows single inheritance it should be trivial to find the most derived class, though the runtime doesn't currently offer a function for this. -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk
Nov 19 2010
parent reply div0 <div0 sourceforge.net> writes:
On 19/11/2010 21:22, Jonathan M Davis wrote:
At runtime, the runtime type info for classes forms a DAG.
 As D only allows single inheritance it should be trivial to find the
 most derived class, though the runtime doesn't currently offer a
 function for this.

Just because an object is able to know what its actual type is - or even its base classes - does not mean that you could ask it what other types exist which are derived from one of its base types or its exact type. Sure, D definitely _could_ provide the necessary type information at runtime (C# and Java do that sort of thing - which is why thy can have runtime reflection), but it doesn't. At best, you can get information on the types of a particular object from that object, not the types which exist in general. - Jonathan M Davis

So just ignore the bit about dynamic cast completely then and repeat your first incorrect assertion. Yes D and C++ do provide a limited amout of runtime type information. It's called RTTI surprisingly enough. *cough* Dynamic cast, *explicitly* asks at *runtime* if some base class can be converted to a *more derived* class. You *can not* do that unless base classes know about the classes which *inherit from* them. -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk
Nov 19 2010
parent div0 <div0 sourceforge.net> writes:
On 19/11/2010 21:58, Jonathan M Davis wrote:

 On Friday, November 19, 2010 13:37:45 div0 wrote:
 The type info has information on that type and its base classes, not all of the
 classes in its class hierarchy. That's enough to properly cast the object and
 whatnot, but not enough to enquire about what derived classes may or may not
 exist.

 - Jonathan M Davis

Yes, Sorry, I skipped a (rather large) step there. I tend to do that a lot, specially when beer is involved. (it's Friday night!). All the info is available; each typeinfo is compiled into the exe, with a specific mangled signature. So on windozes at least it's quite easy (in principle ) to query through all symbols, find all the typeinfos and so find out all the deriving classes. Though as you & I both said it's not currently part of the runtime; and something probably worth adding. But that's all kind of by the point, the OP was about doing it at compile time; which can't be done and seems pointless anyway unless you are doing CRTP which involves templates and that also wasn't wanted. Ergh. I really should ignore this newsgroup on Fridays, I never get anything useful done! :) -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk
Nov 19 2010
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday 19 November 2010 12:56:38 Steven Schveighoffer wrote:
 On Fri, 19 Nov 2010 15:54:08 -0500, Michal Minich
 
 <michal.minich gmail.com> wrote:
 On Fri, 19 Nov 2010 20:50:13 +0000, Michal Minich wrote:
 How do I solve this, without parametrizing class.
 
 class Base {
 
     void foo () { I want get somehow to type *Derived2* at CT }
 
 }
 
 class Derived1 : Base { }
 class Derived2 : Base { }

By making mistake, I realized that it is not possible :) The last line should be: class Derived2 : Derived1 { } The *Base* has two most derived classes in the first example. Anyway, is it somehow possible to iterate derived classes if I only know base class? At CT.

No. You don't know all the derived classes until link time, and there's no doing anything except linking at link time. You should be able to find out at runtime which classes are derived from Base.

And how would you know that at runtime? All reflection in D at this point is compile-time reflection, and that isn't going to help you any here (for the very reasons that you list). I don't see how you could determine which classes are derived from a particular class at runtime. You could use typeof() to determine what the exact type of a reference is, but that wouldn't help you determine what derived classes exist for a particular type. What you'd really need is runtime reflection, which D doesn't have. - Jonathan M Davis
Nov 19 2010
prev sibling next sibling parent Kagamin <spam here.lot> writes:
Michal Minich Wrote:

 On Fri, 19 Nov 2010 20:50:13 +0000, Michal Minich wrote:
 
 How do I solve this, without parametrizing class.
 
 class Base {
     void foo () { I want get somehow to type *Derived2* at CT }
 }
 
 class Derived1 : Base { }
 class Derived2 : Base { }

By making mistake, I realized that it is not possible :) The last line should be: class Derived2 : Derived1 { } The *Base* has two most derived classes in the first example. Anyway, is it somehow possible to iterate derived classes if I only know base class? At CT.

__traits(allMembers, moduleWithDerivedClasses) iterate over them and check
Nov 20 2010
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 19 Nov 2010 16:05:40 -0500, Jonathan M Davis <jmdavisProg gmx.com>  
wrote:

 On Friday 19 November 2010 12:56:38 Steven Schveighoffer wrote:
 On Fri, 19 Nov 2010 15:54:08 -0500, Michal Minich

 <michal.minich gmail.com> wrote:
 On Fri, 19 Nov 2010 20:50:13 +0000, Michal Minich wrote:
 How do I solve this, without parametrizing class.

 class Base {

     void foo () { I want get somehow to type *Derived2* at CT }

 }

 class Derived1 : Base { }
 class Derived2 : Base { }

By making mistake, I realized that it is not possible :) The last line should be: class Derived2 : Derived1 { } The *Base* has two most derived classes in the first example. Anyway, is it somehow possible to iterate derived classes if I only

 base class? At CT.

No. You don't know all the derived classes until link time, and there's no doing anything except linking at link time. You should be able to find out at runtime which classes are derived from Base.

And how would you know that at runtime? All reflection in D at this point is compile-time reflection, and that isn't going to help you any here (for the very reasons that you list).

All the ModuleInfo and ClassInfo types are stored in an array somewhere in the runtime. Take a look at Object.factory() for an example of how to find a class. If you can iterate all the ClassInfo's in the application, you can find out which ones derive from a base. -Steve
Nov 22 2010
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday 19 November 2010 12:50:13 Michal Minich wrote:
 How do I solve this, without parametrizing class.
 
 class Base {
     void foo () { I want get somehow to type *Derived2* at CT }
 }
 
 class Derived1 : Base { }
 class Derived2 : Base { }

I think that you're going to give more details about what you're tring to do. And aside from the fact that it's generally bad practice to have your base classes know anything about your derived clases, what makes Derived2 "more" derived than Derived1? (since your topic seems to indicate that you somehow want it to use Derived2 rather than Derived1 because it's "more" derived) - Jonathan M Davis
Nov 19 2010
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday 19 November 2010 13:12:40 div0 wrote:
 On 19/11/2010 21:05, Jonathan M Davis wrote:
 On Friday 19 November 2010 12:56:38 Steven Schveighoffer wrote:
 
 And how would you know that at runtime? All reflection in D at this point
 is compile-time reflection, and that isn't going to help you any here
 (for the very reasons that you list). I don't see how you could
 determine which classes are derived from a particular class at runtime.
 You could use typeof() to determine what the exact type of a reference
 is, but that wouldn't help you determine what derived classes exist for
 a particular type. What you'd really need is runtime reflection, which D
 doesn't have.
 
 - Jonathan M Davis

How would dynamic cast work if you can't find out the inheriting classes from a reference? At runtime, the runtime type info for classes forms a DAG. As D only allows single inheritance it should be trivial to find the most derived class, though the runtime doesn't currently offer a function for this.

Just because an object is able to know what its actual type is - or even its base classes - does not mean that you could ask it what other types exist which are derived from one of its base types or its exact type. Sure, D definitely _could_ provide the necessary type information at runtime (C# and Java do that sort of thing - which is why thy can have runtime reflection), but it doesn't. At best, you can get information on the types of a particular object from that object, not the types which exist in general. - Jonathan M Davis
Nov 19 2010
prev sibling next sibling parent Michal Minich <michal.minich gmail.com> writes:
On Fri, 19 Nov 2010 21:37:45 +0000, div0 wrote:

 On 19/11/2010 21:22, Jonathan M Davis wrote: At runtime, the runtime
 type info for classes forms a DAG.
 As D only allows single inheritance it should be trivial to find the
 most derived class, though the runtime doesn't currently offer a
 function for this.

Just because an object is able to know what its actual type is - or even its base classes - does not mean that you could ask it what other types exist which are derived from one of its base types or its exact type. Sure, D definitely _could_ provide the necessary type information at runtime (C# and Java do that sort of thing - which is why thy can have runtime reflection), but it doesn't. At best, you can get information on the types of a particular object from that object, not the types which exist in general. - Jonathan M Davis

So just ignore the bit about dynamic cast completely then and repeat your first incorrect assertion. Yes D and C++ do provide a limited amout of runtime type information. It's called RTTI surprisingly enough. *cough* Dynamic cast, *explicitly* asks at *runtime* if some base class can be converted to a *more derived* class. You *can not* do that unless base classes know about the classes which *inherit from* them.

In current dmd, when you make a cast like: cast (Derived) base, you explicitly mentioning the *Derived* type. Its typeinfo contains info about classes it derives from, so it the cast just check if type of "base" is one of them. Compiler currently does not push informations from Derived classes to base class type info, so it is not possible currently to find out what I wanted.
Nov 19 2010
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, November 19, 2010 13:37:45 div0 wrote:
 On 19/11/2010 21:22, Jonathan M Davis wrote:
 At runtime, the runtime type info for classes forms a DAG.
 
 As D only allows single inheritance it should be trivial to find the
 most derived class, though the runtime doesn't currently offer a
 function for this.

Just because an object is able to know what its actual type is - or even its base classes - does not mean that you could ask it what other types exist which are derived from one of its base types or its exact type. Sure, D definitely _could_ provide the necessary type information at runtime (C# and Java do that sort of thing - which is why thy can have runtime reflection), but it doesn't. At best, you can get information on the types of a particular object from that object, not the types which exist in general. - Jonathan M Davis

So just ignore the bit about dynamic cast completely then and repeat your first incorrect assertion. Yes D and C++ do provide a limited amout of runtime type information. It's called RTTI surprisingly enough. *cough* Dynamic cast, *explicitly* asks at *runtime* if some base class can be converted to a *more derived* class. You *can not* do that unless base classes know about the classes which *inherit from* them.

Yes. I know that. What I'm saying that you can't do is ask whether the type of an object has any derived types, let alone get a list of them. There's enough information there to get a list of the classes that a particular object has as its exact type and base classes, so you could (assuming that D gave you access to that information) figure out whether a particular base class has any derived classes (since you can see one of them), but there's no information there on whatever other classes might be derived from that class, and if it's the exact type that you're looking at, you don't have _any_ information on its derived classes. So, class D : C //(with C being derived from B, and B being derived from A) {} means that a D object has enough information to know about D, C, B, and A. but it wouldn't know about other classes such as class E : D {} class Q : C {} The type info has information on that type and its base classes, not all of the classes in its class hierarchy. That's enough to properly cast the object and whatnot, but not enough to enquire about what derived classes may or may not exist. - Jonathan M Davis
Nov 19 2010
prev sibling next sibling parent "Manfred_Nowak" <svv1999 hotmail.com> writes:
Michal Minich wrote:

 I want get somehow to type *Derived2* at CT

I miss the motivation: why would one wnat to have that at compile time? -manfred
Nov 22 2010
prev sibling next sibling parent Michal Minich <michal.minich gmail.com> writes:
V Mon, 22 Nov 2010 16:38:11 +0000, Manfred_Nowak wrote:

 Michal Minich wrote:
 
 I want get somehow to type *Derived2* at CT

I miss the motivation: why would one wnat to have that at compile time? -manfred

http://www.google.com/search?q=curiously+recurring+template
Nov 22 2010
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 19 Nov 2010 16:48:50 -0500, Michal Minich  
<michal.minich gmail.com> wrote:

 On Fri, 19 Nov 2010 21:37:45 +0000, div0 wrote:

 On 19/11/2010 21:22, Jonathan M Davis wrote: At runtime, the runtime
 type info for classes forms a DAG.
 As D only allows single inheritance it should be trivial to find the
 most derived class, though the runtime doesn't currently offer a
 function for this.

Just because an object is able to know what its actual type is - or even its base classes - does not mean that you could ask it what other types exist which are derived from one of its base types or its exact type. Sure, D definitely _could_ provide the necessary type information at runtime (C# and Java do that sort of thing - which is why thy can have runtime reflection), but it doesn't. At best, you can get information on the types of a particular object from that object, not the types which exist in general. - Jonathan M Davis

So just ignore the bit about dynamic cast completely then and repeat your first incorrect assertion. Yes D and C++ do provide a limited amout of runtime type information. It's called RTTI surprisingly enough. *cough* Dynamic cast, *explicitly* asks at *runtime* if some base class can be converted to a *more derived* class. You *can not* do that unless base classes know about the classes which *inherit from* them.

In current dmd, when you make a cast like: cast (Derived) base, you explicitly mentioning the *Derived* type. Its typeinfo contains info about classes it derives from, so it the cast just check if type of "base" is one of them.

Given two types, you can determine if they are related at compile-time. Derived classes contain pointers to their base class' classinfo.
 Compiler currently does not push informations from Derived classes to
 base class type info, so it is not possible currently to find out what I
 wanted.

Not at compile time. The runtime contains all the classinfos, so you can iterate them all and find ones that derive from your base. -Steve
Nov 22 2010