Thread overview
Arrays of many different (sub)classes
Apr 24, 2010
Joseph Wakeling
Apr 24, 2010
Robert Clipsham
Apr 25, 2010
Joseph Wakeling
Apr 25, 2010
Mihail Strashun
Apr 25, 2010
Robert Clipsham
Apr 26, 2010
Ali Çehreli
April 24, 2010
Hello all,

Occasionally in C++ I find it useful to build an array which contains classes of multiple different types all using the same interface -- by constructing an array of pointers to some common base class, e.g.

class BaseClass {
    // blah, blah ...
};

class A : BaseClass {
    // ... blah ...
};

class C : BaseClass {
    // ... blah ...
};

int main()
{
    vector<BaseClass *> vec;
    vec.push_back(new A());
    vec.push_back(new C());
    // etc. etc.
}

(This code might be wrong; I'm just typing it to give the idea.  And in practice, I usually do not use 'new' statements but pass pointers to already-existing objects...:-)

Anyway, the point is that at the end of the day I have an array of different objects with a common interface.  What's the appropriate way to achieve the same effect in D?

Thanks & best wishes,

    -- Joe
April 24, 2010
On 24/04/10 20:06, Joseph Wakeling wrote:
> Hello all,
>
> Occasionally in C++ I find it useful to build an array which contains
> classes of multiple different types all using the same interface -- by
> constructing an array of pointers to some common base class, e.g.
>
> class BaseClass {
>      // blah, blah ...
> };
>
> class A : BaseClass {
>      // ... blah ...
> };
>
> class C : BaseClass {
>      // ... blah ...
> };
>
> int main()
> {
>      vector<BaseClass *>  vec;
>      vec.push_back(new A());
>      vec.push_back(new C());
>      // etc. etc.
> }
>
> (This code might be wrong; I'm just typing it to give the idea.  And in
> practice, I usually do not use 'new' statements but pass pointers to
> already-existing objects...:-)
>
> Anyway, the point is that at the end of the day I have an array of
> different objects with a common interface.  What's the appropriate way
> to achieve the same effect in D?
>
> Thanks&  best wishes,
>
>      -- Joe

This should do what you want:
----
class BaseClass {
    // blah, blah ...
}

class A : BaseClass {
    // ... blah ...
}

class C : BaseClass {
    // ... blah ...
}

int main()
{
    BaseClass[] vec;
    vec ~= new A;
    vec ~= new C;
    // etc. etc.
}
----
April 25, 2010
Robert Clipsham wrote:
> This should do what you want:

Thanks! :-)

Is it possible to do this with an interface instead of a base class? I'm not familiar with how the former work ...

Best wishes,

    -- Joe
April 25, 2010
On 04/25/2010 04:47 PM, Joseph Wakeling wrote:
> Robert Clipsham wrote:
>> This should do what you want:
>
> Thanks! :-)
>
> Is it possible to do this with an interface instead of a base class?
> I'm not familiar with how the former work ...
>
> Best wishes,
>
>      -- Joe

April 25, 2010
On 25/04/10 14:47, Joseph Wakeling wrote:
> Robert Clipsham wrote:
>> This should do what you want:
>
> Thanks! :-)
>
> Is it possible to do this with an interface instead of a base class?
> I'm not familiar with how the former work ...
>
> Best wishes,
>
>      -- Joe

Yes it is, providing the base doesn't implement any methods, eg:

----
interface I
{
  int foobar();
  // The following line will cause an error when uncommented, as
  // you cannot implement methods in an interface
  // void baz() {}
}

class C : I
{
  int foobar() { return 1; }
}

class D : I
{
  int foobar() { return 2; }
}

import std.stdio;

void main()
{
  I[] arr;
  arr ~= new C;
  arr ~= new D;
  foreach( el; arr )
    writefln( "%d", el.foobar() );
}
----
Prints:
1
2

You could also use an abstract class instead of an interface if you want to implement some of the methods.
April 26, 2010
Robert Clipsham wrote:

> interface I
> {
>   int foobar();
>   // The following line will cause an error when uncommented, as
>   // you cannot implement methods in an interface
>   // void baz() {}
> }

Just to be complete: interfaces can have static or final functions in D2:

    static void baz() {}
    final void baz_2() {}

Ali