March 06, 2014 Re: Best way to reference an array in a child class... | ||||
---|---|---|---|---|
| ||||
Posted in reply to captain_fid | On Thu, 06 Mar 2014 17:05:12 -0500, captain_fid <bell.hue@gmail.com> wrote:
> On Thursday, 6 March 2014 at 21:26:11 UTC, Ali Çehreli wrote:
>> On 03/06/2014 12:02 PM, Steven Schveighoffer wrote:
>>
>> > The best way
>> > to reference an array in a child class, especially one of a
>> static type,
>> > is to not have another copy in the child class :)
>>
>> Agreed. Alternatively, a member function in the child class could return a slice.
>>
>> Ali
>
> Steve, thanks for the link and the nicely written article. Also for the assessment on pointer syntax, I'd love to avoid if possible (especially w/ limitations you noted).
>
> I had been spending time over at http://dlang.org/arrays.html and had forgotten (or never understood) dynamic arrays were passed by slices. That link only talks about passing static arrays (IIRC). Keeping track of 'what being passed how' is tough for this programmer.
>
> Your suggestion Ali (of not accessing the base member in the child was great) and it works properly.
>
> Believe if I understand what you are suggesting above is never to have the array in base? simply retrieve slice through the child member function?
I think what Ali means is:
class A
{
abstract S[] items();
}
class B : A
{
S[] _items = [ {10, "first"}, {20, "second"}];
override S[] items() { return _items;}
}
What I was saying is, if you know the items are going to be stored in the object, just store them in the base:
class A
{
S[] items;
}
class B : A
{
this() {items = [ {10, "first"}, {20, "second"}];}
}
This way, both the derived and the base will always see the same items, and you only store it in the object once. Obviously if you store the items elsewhere in some derivatives, Ali's idea is preferable.
-Steve
|
March 06, 2014 Re: Best way to reference an array in a child class... | ||||
---|---|---|---|---|
| ||||
Posted in reply to captain_fid | On 03/06/2014 02:05 PM, captain_fid wrote: > Your suggestion Ali (of not accessing the base member in the child was > great) and it works properly. > > Believe if I understand what you are suggesting above is never to have > the array in base? simply retrieve slice through the child member function? Yes, but it also depends on the need. I assumed that the base class needed a slice of elements from the base class. Will the slice of elements ever change? If no, then the base could take them at construction time and use them in the future: import std.stdio; class B { const(int[]) items; this(const(int[]) items) // <-- Requires elements // during construction { this.items = items; } final void do_work() { writeln(items); } } class D : B { this() { super([ 1, 2, 3]); // Items are determined here } } void main() { auto d = new D(); d.do_work(); } Alternatively, and especially if the elements will change at run time, the derived class can hold on to the elements and can provide them as the base class needs: import std.stdio; class B { abstract const(int)[] items(); final void do_work() { writeln(items()); } } class D : B { int[] myItems; this() { myItems = [ 1, 2, 3]; } void add(int[] items) { myItems ~= items; } override const(int)[] items() { return myItems; } } void main() { auto d = new D(); d.do_work(); // 1, 2, 3 // Add more later on d.add([ 4, 5, 6 ]); d.do_work(); // 1, 2, 3, 4, 5, 6 } Ali |
March 06, 2014 Re: Best way to reference an array in a child class... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Thursday, 6 March 2014 at 22:16:50 UTC, Steven Schveighoffer wrote:
> On Thu, 06 Mar 2014 17:05:12 -0500, captain_fid <bell.hue@gmail.com> wrote:
>
>> On Thursday, 6 March 2014 at 21:26:11 UTC, Ali Çehreli wrote:
>>> On 03/06/2014 12:02 PM, Steven Schveighoffer wrote:
>>>
>>> > The best way
>>> > to reference an array in a child class, especially one of a
>>> static type,
>>> > is to not have another copy in the child class :)
>>>
>>> Agreed. Alternatively, a member function in the child class could return a slice.
>>>
>>> Ali
>>
>> Steve, thanks for the link and the nicely written article. Also for the assessment on pointer syntax, I'd love to avoid if possible (especially w/ limitations you noted).
>>
>> I had been spending time over at http://dlang.org/arrays.html and had forgotten (or never understood) dynamic arrays were passed by slices. That link only talks about passing static arrays (IIRC). Keeping track of 'what being passed how' is tough for this programmer.
>>
>> Your suggestion Ali (of not accessing the base member in the child was great) and it works properly.
>>
>> Believe if I understand what you are suggesting above is never to have the array in base? simply retrieve slice through the child member function?
>
> I think what Ali means is:
>
> class A
> {
> abstract S[] items();
> }
>
> class B : A
> {
> S[] _items = [ {10, "first"}, {20, "second"}];
> override S[] items() { return _items;}
> }
>
> What I was saying is, if you know the items are going to be stored in the object, just store them in the base:
>
> class A
> {
> S[] items;
> }
>
> class B : A
> {
> this() {items = [ {10, "first"}, {20, "second"}];}
> }
>
> This way, both the derived and the base will always see the same items, and you only store it in the object once. Obviously if you store the items elsewhere in some derivatives, Ali's idea is preferable.
>
> -Steve
Yes Steve!
Even if the title of the thread is off, the original intent was what you've shown. For a reason (probably duplicate definitions in base and child) I would end up with items in B and not visible in A.
I didn't understand the syntax for performing the above.
I owe you guys a beer (or something). Definitely a learning lesson.
|
March 06, 2014 Re: Best way to reference an array in a child class... | ||||
---|---|---|---|---|
| ||||
Posted in reply to captain_fid |
>> this() {items = [ {10, "first"}, {20, "second"}];}
strangely enough, when modeling this the first time (using items as a class) and 'new item() syntax) there was no real issue.
I thought using a static array of structs in the children would be more efficient when instantiating the objects. Never mind whether its true or not - Speed isn't a really a concern, learning is.
|
March 06, 2014 Re: Best way to reference an array in a child class... | ||||
---|---|---|---|---|
| ||||
Posted in reply to captain_fid | Well, actually... take it back. When I did try this syntax, I receive(d) the following error. I then went and created this test which I thought couldn't go wrong. with both dmd and gdc ... struct S { int a; string b; } class A { S[] items; abstract void doit(); } class B: A { this() {items = [ {10, "first"}, {20, "second"}];} // line 21 override void doit() { } } (21): Error: found '}' when expecting ';' following statement (21): Error: found ',' instead of statement |
March 07, 2014 Re: Best way to reference an array in a child class... | ||||
---|---|---|---|---|
| ||||
Posted in reply to captain_fid | captain_fid:
> struct S
> {
> int a;
> string b;
> }
>
> class A
> {
> S[] items;
> abstract void doit();
> }
>
> class B: A
> {
> this() {items = [ {10, "first"}, {20, "second"}];} // line 21
> override void doit() { }
> }
>
> (21): Error: found '}' when expecting ';' following statement
> (21): Error: found ',' instead of statement
For reasons I don't know that {} syntax doesn't always work in D. So try:
this() {
this.items = [S(10, "first"), S(20, "second")];
}
Bye,
bearophile
|
March 07, 2014 Re: Best way to reference an array in a child class... | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Friday, 7 March 2014 at 00:10:20 UTC, bearophile wrote:
> captain_fid:
>
>> struct S
>> {
>> int a;
>> string b;
>> }
>>
>> class A
>> {
>> S[] items;
>> abstract void doit();
>> }
>>
>> class B: A
>> {
>> this() {items = [ {10, "first"}, {20, "second"}];} // line 21
>> override void doit() { }
>> }
>>
>> (21): Error: found '}' when expecting ';' following statement
>> (21): Error: found ',' instead of statement
>
> For reasons I don't know that {} syntax doesn't always work in D. So try:
>
> this() {
> this.items = [S(10, "first"), S(20, "second")];
> }
>
> Bye,
> bearophile
Going to have to buy the whole bar a round. Thanks bearophile for the quick fix!
|
March 07, 2014 Re: Best way to reference an array in a child class... | ||||
---|---|---|---|---|
| ||||
Posted in reply to captain_fid | On Thu, 06 Mar 2014 17:44:09 -0500, captain_fid <bell.hue@gmail.com> wrote:
>
>>> this() {items = [ {10, "first"}, {20, "second"}];}
>
> strangely enough, when modeling this the first time (using items as a class) and 'new item() syntax) there was no real issue.
>
> I thought using a static array of structs in the children would be more efficient when instantiating the objects. Never mind whether its true or not - Speed isn't a really a concern, learning is.
I missed this the first time. That is a difference between my code and your code. Mine creates a new instance of an array on *object* initialization, yours creates ONE instance of an array, that all objects share.
This is not necessarily a good thing. Because you've created a mutable version of the array. I believe it is initialized on startup from the heap.
One really bad thing is, the same array is used if you initialize from multiple threads. And it's mutable, making it implicitly shared even though it shouldn't be. You should make the array immutable and static, or else initialize it in the constructor. I don't know your use case, so it's hard to say what you should do.
-Steve
|
March 07, 2014 Re: Best way to reference an array in a child class... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Friday, 7 March 2014 at 13:57:31 UTC, Steven Schveighoffer wrote: > On Thu, 06 Mar 2014 17:44:09 -0500, captain_fid <bell.hue@gmail.com> wrote: > >> >>>> this() {items = [ {10, "first"}, {20, "second"}];} >> >> strangely enough, when modeling this the first time (using items as a class) and 'new item() syntax) there was no real issue. >> >> I thought using a static array of structs in the children would be more efficient when instantiating the objects. Never mind whether its true or not - Speed isn't a really a concern, learning is. > > I missed this the first time. That is a difference between my code and your code. Mine creates a new instance of an array on *object* initialization, yours creates ONE instance of an array, that all objects share. > > This is not necessarily a good thing. Because you've created a mutable version of the array. I believe it is initialized on startup from the heap. > > One really bad thing is, the same array is used if you initialize from multiple threads. And it's mutable, making it implicitly shared even though it shouldn't be. You should make the array immutable and static, or else initialize it in the constructor. I don't know your use case, so it's hard to say what you should do. > > -Steve >> I don't know your use case, so it's hard to say what you should do. Steve, I don't think I know my use case -- So it's not you. I'm attempting to model hardware, where 'items' in this case are an static array of registers. Single threaded (for now). Mainly, this a learning opportunity to get a better understanding of D for future comparison (vs. C++). > This is not necessarily a good thing. Because you've created a mutable version of the array. I believe it is initialized on startup from the heap. Lot to learn. I understand initialized from the heap, but do you mean at program startup, or object instantiation? If program, I would have expected that with __gshared (globals) only, not with this. > One really bad thing is, the same array is used if you initialize from multiple threads. And it's mutable, making it implicitly shared even though it shouldn't be. You should make the array immutable and static, or else initialize it in the constructor. I appreciate your suggestions and the patience. |
Copyright © 1999-2021 by the D Language Foundation