www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - is there any way to get a list of classes that inherit a class?

reply hyp <noreply gmail.com> writes:
Hello,

I know you can easily get the base class of some class in D. However is  
there any way to get a list of classes that inherit a given class?
I was reading around the docs, but couldn't find anything :/. But maybe  
someone knows how to do it?
Feb 13 2011
next sibling parent reply Kevin Bealer <kevindangerbealer removedanger.gmail.com> writes:
I don't know if you can find all of them easily but you can find the
instantiated
ones by adding a line to the Foo constructor as shown here.

Two limits:

1. This doesn't report Bar itself since a Bar object is never created; however
in
a sense a 'Bar' object was created when Baz and Qux are created.  Since you know
how to get the parent of a type you should be able to fix this if desired.

2. As mentioned you can't get the non-instantiated classes this way -- it only
detects classes as 'new' is called on them.  By the way this wouldn't work in
C++
because in C++ object identity changes as the successive constructors are called
-- it would just report Foo.

3. Of course you could add a pure virtual function to the class...

testrtti.d:

import std.stdio;

int[string] fooTypes;

class Foo {
    this() { fooTypes[this.classinfo.name] = 1; }
};

class Bar : Foo {
};

class Baz : Bar {
};

class Qux : Baz {
};

int main()
{
    Foo a = new Foo;
    Foo b = new Qux;
    Bar f = new Baz;

    foreach(key, value; fooTypes) {
        writefln("foo subtype: %s", key);
    }

    return 0;
}

foo subtype: testrtti.Foo
foo subtype: testrtti.Baz
foo subtype: testrtti.Qux

Kevin
Feb 13 2011
parent hyp <noreply gmail.com> writes:
On Sun, 13 Feb 2011 19:38:23 -0000, Kevin Bealer  
<kevindangerbealer removedanger.gmail.com> wrote:

 I don't know if you can find all of them easily but you can find the  
 instantiated
 ones by adding a line to the Foo constructor as shown here.

 Two limits:

 1. This doesn't report Bar itself since a Bar object is never created;  
 however in
 a sense a 'Bar' object was created when Baz and Qux are created.  Since  
 you know
 how to get the parent of a type you should be able to fix this if  
 desired.

 2. As mentioned you can't get the non-instantiated classes this way --  
 it only
 detects classes as 'new' is called on them.  By the way this wouldn't  
 work in C++
 because in C++ object identity changes as the successive constructors  
 are called
 -- it would just report Foo.

 3. Of course you could add a pure virtual function to the class...

 testrtti.d:

 import std.stdio;

 int[string] fooTypes;

 class Foo {
     this() { fooTypes[this.classinfo.name] = 1; }
 };

 class Bar : Foo {
 };

 class Baz : Bar {
 };

 class Qux : Baz {
 };

 int main()
 {
     Foo a = new Foo;
     Foo b = new Qux;
     Bar f = new Baz;

     foreach(key, value; fooTypes) {
         writefln("foo subtype: %s", key);
     }

     return 0;
 }

 foo subtype: testrtti.Foo
 foo subtype: testrtti.Baz
 foo subtype: testrtti.Qux

 Kevin
Thanks for reply, I'm going to test it out now. I guess there's no chance of getting the derived classes during the compile time, so I'll have to use this runtime approach.
Feb 13 2011
prev sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
hyp <noreply gmail.com> wrote:

 Hello,

 I know you can easily get the base class of some class in D. However is  
 there any way to get a list of classes that inherit a given class?
 I was reading around the docs, but couldn't find anything :/. But maybe  
 someone knows how to do it?
This question is probably better asked in digitalmars.D.learn. As for the solution, this works: TypeInfo_Class[] getSubClasses( Object o ) { typeof( return ) result; auto base = o.classinfo; foreach ( m; ModuleInfo ) { foreach ( c; m.localClasses ) { auto a = c; while ( a && a != base ) { a = a.base; } if ( a == base ) { result ~= c; } } } return result; } class A {} class B : A {} void main( ) { writeln( getSubClasses( new A() ) ); } Do note however, that templated classes do not show up in this search. -- Simen
Feb 13 2011