Accessing outer class attribute from inner struct

Moritz Maxeiner via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Aug 28 16:12:40 PDT 2017


On Monday, 28 August 2017 at 22:47:12 UTC, Andre Pany wrote:
> On Monday, 28 August 2017 at 22:28:18 UTC, Moritz Maxeiner 
> wrote:
>> On Monday, 28 August 2017 at 21:52:58 UTC, Andre Pany wrote:
>>> [...]
>>>
>>> To make my question short:) If ColumnsArray is a class I can 
>>> access the attribute "reference" but not if it is a struct. I 
>>> would rather prefer a struct, but with a struct
>>> it seems I cannot access "reference".
>>>
>>> How can I access "reference" from my inner struct?
>>>
>>> [...]
>>
>> Add an explicit class reference member to to it:
>> ---
>> class TCustomGrid: TCustomPresentedScrollBox
>> {
>> 	struct ColumnsArray
>> 	{
>> 		TCustomGrid parent;
>>
>> 		TColumn opIndex(int index)
>> 		{
>> 			int r = getIntegerIndexedPropertyReference(reference, 
>> "Columns", index);
>> 			return new TColumn(r);
>> 		}
>> 	}
>> 	
>> 	ColumnsArray Columns;
>>
>> 	this()
>> 	{
>> 		Columns = ColumnsArray(this);
>> 	}
>> ...
>> }
>> ---
>>
>> Nesting structs inside anything other than functions[1] is for 
>> visibility/protection encapsulation and namespacing only.
>>
>> [1] non-static structs in functions are special as they have 
>> access to the surrounding stack frame
>
> Unfortunately thats not possible. ColumnsArray and the 
> attribute will become a string mixin to avoid boilerplate.
>
> It would be error prone if I have to initialize them in the 
> constructor too. I want just 1 single coding line for this 
> property. That is also the reason I do not want to use a class, 
> as I would have to initialize them in the constructor.

---
class C
{
     struct S
     {
     }
     S s;
}
---

is semantically equivalent to

---
struct S
{
}

class C
{
     S s;
}
---

with the two differences being
- namespacing (outside of C one has to use C.S to access S)
- you can protect the visibility of the S from outside the module 
C resides in via private,public, etc.

In both cases S doesn't inherently how about C, which means a 
solution using default initialization is not feasible, as S.init 
can't know about any particular instance of C.
I don't think there's any way for you to avoid using a class 
constructor.


More information about the Digitalmars-d-learn mailing list