Problem using Interfce

Stephen Jones siwenjo at gmail.com
Mon May 14 11:49:58 PDT 2012


On Monday, 14 May 2012 at 18:39:13 UTC, Stephen Jones wrote:
> On Monday, 14 May 2012 at 11:49:21 UTC, simendsjo wrote:
>> On Mon, 14 May 2012 13:08:06 +0200, Stephen Jones 
>> <siwenjo at gmail.com> wrote:
>>
>>> I have a Widget interface which I was hoping would allow me to
>>> subsume a set of classes {Button, Cursor, etc} as being 
>>> Widgets
>>> so I could keep an array of buttons, cursors, etc by 
>>> initializing
>>> them as Widgets.
>>>
>>> private Widget[] widgets;
>>> ...
>>> widgets[widx++]=new Button(fmt, unitw, unith, count);
>>> ...
>>> widgets[widx++]=new Cursor(unitw, unith, count);
>>>
>>>
>>> But when I try to step through the array I cannot access 
>>> Button
>>> or Cursor variables because "Error: no property 'vertStart' 
>>> for
>>> type 'Widget.Widget'":
>>>
>>> foreach(Widget w; widgets){
>>>    glDrawArrays(GL_TRIANGLES, w.vertStart, w.vertCount);
>>> }
>>>
>>>
>>> I am used to languages where the w under consideration in any
>>> iteration would be known to have been initialized as a Button 
>>> or
>>> Cursor, etc, and the value of vertStart would be found without
>>> error. I cannot cast without wrapping everything in if
>>> statements. I could use access functions but I would prefer 
>>> not
>>> to incur function overhead. Is there a solution?
>>>
>>
>> If the language/runtime knows the actual underlying class for 
>> the interface, some overhead must occur behind the scenes.
>> This seems more like a design issue. Why doesn't the interface 
>> contain vertStart etc? Should you have a base class that 
>> contains these? Or another interface?
>>
>> import std.algorithm, std.stdio;
>>
>> interface Widget {} // common widget
>> class SomeWidget : Widget {}
>>
>> interface VerticeWidget : Widget { // Might be drawn
>>    @property int vertStart();
>> }
>>
>> class Button : VerticeWidget {
>>    @property int vertStart() { return 10; }
>> }
>>
>> // only fetch VerticeWidgets
>> @property auto verticeWidgets(Widget[] widgets)
>> {
>>    return widgets
>>        .map!((a) => cast(VerticeWidget)a)()
>>        .filter!((a) => a !is null)();
>> }
>>
>> void main() {
>>    Widget[] widgets;
>>    widgets ~= new SomeWidget();
>>    widgets ~= new Button();
>>    widgets ~= new SomeWidget();
>>
>>    // this only includes the Button (prints 10), which has 
>> vertStart as it derives from VerticeWidget
>>    foreach(widget; widgets.verticeWidgets)
>>    {
>>        writeln(widget.vertStart);
>>    }
>> }
>> /
>
> I haven't been clear, vertStart and vertCount are variables not
> functions:
>
> public int vertStart, vertCount=6;
>
> A solution that should work is to dump extending the classes and
> make an array of void pointers that point, some to Button
> objects, and some to Cursor objects but I do not know the syntax
> for doing this, or even if it is possible to have an array of
> pointers pointing at different classes of objects. I should 
> think
> it should be possible given that, on a 32 bit machine, pointers
> are all 32 bit ints so it is basically an array of ints that is
> being created, only those ints contain the address of a bunch of
> different types of objects.
>
> Thankyou simendsjo for the code you provided it has helped on
> other matters.

Sorry, no edit functionality. I have just been re-reading 
property syntax and see it is the same as c# getter setter deals. 
My understanding is that c# getter setters were simply syntactic 
sugar which under the hood called standard functions incurring 
the standard function overhead. Is this the same with D, or does 
D implement properties using pointers to the required data fields?


More information about the Digitalmars-d-learn mailing list