February 14, 2008 Re: *final* class member (D2) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Neil Vice | On Thu, 14 Feb 2008 08:53:23 +0900, Neil Vice wrote:
>
> "Denton Cockburn" <diboss@hotmail.com> wrote in message news:pan.2008.02.13.22.55.38.263151@hotmail.com...
>> On Wed, 13 Feb 2008 14:33:33 -0500, Steven Schveighoffer wrote:
>>
>>> "Denton Cockburn" wrote
>>>> How do I do this? I'm trying to create a class member here that needs
>>>> to
>>>> be initialized in the constructor, but cannot be changed later.
>>>>
>>>> class A
>>>> {
>>>> (const doesn't work) real delegate() dg; // this is that
>>>> function;
>>>>
>>>> this(real delegate() dg) { this.dg = dg; }
>>>> }
>>>>
>>>> class B
>>>> {
>>>> real foo() { return 3.5; }
>>>> }
>>>>
>>>> class C
>>>> {
>>>> real foo() { return 4.5; }
>>>> }
>>>>
>>>> void main()
>>>> {
>>>> auto b = new B;
>>>> auto a = new A(&b.foo);
>>>> auto c = new C;
>>>> a.fitness = &c.foo; // I want this to be an error
>>>> }
>>>
>>> um... did you try encapsulation?
>>>
>>> class A
>>> {
>>> private real delegate() _dg;
>>>
>>> public real dg()
>>> {
>>> return _dg();
>>> }
>>>
>>> this(real delegate() dg) { this._dg = dg; }
>>> }
>>>
>>> -Steve
>>
>> This was the workaround I used as well.
>> I don't like it because of the extra level of indirection (I end up
>> calling 2 functions instead of 1). I don't consider this very efficient
>> or convenient.
>
> I would have expected the dg() method (or property I guess) in the above to be inlined, possibly requiring a final specifier? In that case I don't see any reduction in performance.
>
> As a matter of interest the following code is fairly equivalent but results in some bizarre property/delegate interaction:
>
> class A
> {
> private real delegate() _dg;
>
> this(real delegate() dg) { this._dg = dg; }
>
> public real delegate() dg()
> {
> return _dg;
> }
> }
>
> // Sample usage
> public void example(real delegate() dg)
> {
> A test = new A(dg);
> // test.dg - Evaluates to the delegate dg
> // test.dg() - Also evaluates to the delegate dg
> test.dg()() // Required to actually execute the delegate
> }
>
> Neil
isn't that because you have the function (test.dg) return a "real
delegate()" so: test.dg() returns a delegate, and test.dg()() calls that
delegate.
|
February 14, 2008 Re: *final* class member (D2) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Denton Cockburn | "Denton Cockburn" <diboss@hotmail.com> wrote in message news:pan.2008.02.14.00.52.40.389590@hotmail.com... > On Thu, 14 Feb 2008 08:53:23 +0900, Neil Vice wrote: > >> >> "Denton Cockburn" <diboss@hotmail.com> wrote in message news:pan.2008.02.13.22.55.38.263151@hotmail.com... >>> On Wed, 13 Feb 2008 14:33:33 -0500, Steven Schveighoffer wrote: >>> >>>> "Denton Cockburn" wrote >>>>> How do I do this? I'm trying to create a class member here that needs >>>>> to >>>>> be initialized in the constructor, but cannot be changed later. >>>>> >>>>> class A >>>>> { >>>>> (const doesn't work) real delegate() dg; // this is that >>>>> function; >>>>> >>>>> this(real delegate() dg) { this.dg = dg; } >>>>> } >>>>> >>>>> class B >>>>> { >>>>> real foo() { return 3.5; } >>>>> } >>>>> >>>>> class C >>>>> { >>>>> real foo() { return 4.5; } >>>>> } >>>>> >>>>> void main() >>>>> { >>>>> auto b = new B; >>>>> auto a = new A(&b.foo); >>>>> auto c = new C; >>>>> a.fitness = &c.foo; // I want this to be an error >>>>> } >>>> >>>> um... did you try encapsulation? >>>> >>>> class A >>>> { >>>> private real delegate() _dg; >>>> >>>> public real dg() >>>> { >>>> return _dg(); >>>> } >>>> >>>> this(real delegate() dg) { this._dg = dg; } >>>> } >>>> >>>> -Steve >>> >>> This was the workaround I used as well. >>> I don't like it because of the extra level of indirection (I end up >>> calling 2 functions instead of 1). I don't consider this very efficient >>> or convenient. >> >> I would have expected the dg() method (or property I guess) in the above >> to >> be inlined, possibly requiring a final specifier? In that case I don't >> see >> any reduction in performance. >> >> As a matter of interest the following code is fairly equivalent but >> results >> in some bizarre property/delegate interaction: >> >> class A >> { >> private real delegate() _dg; >> >> this(real delegate() dg) { this._dg = dg; } >> >> public real delegate() dg() >> { >> return _dg; >> } >> } >> >> // Sample usage >> public void example(real delegate() dg) >> { >> A test = new A(dg); >> // test.dg - Evaluates to the delegate dg >> // test.dg() - Also evaluates to the delegate dg >> test.dg()() // Required to actually execute the delegate >> } >> >> Neil > > isn't that because you have the function (test.dg) return a "real > delegate()" so: test.dg() returns a delegate, and test.dg()() calls that > delegate. Yes, however by similar logic one could conclude that because the property "test.dg" returns a "real delegate()" that "test.dg()" should execute the delegate and return a real. |
February 14, 2008 Re: *final* class member (D2) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Denton Cockburn | On Wed, 13 Feb 2008 10:59:26 -0500, Denton Cockburn wrote: > How do I do this? I'm trying to create a class member here that needs to be initialized in the constructor, but cannot be changed later. The code below seems to work for me (DMD v2.008) class A { const real delegate() dg; // this is that function; this(const real delegate() dg) { this.dg = dg; } } class B { real foo() { return 3.5; } } class C { real foo() { return 4.5; } } void main() { auto b = new B; auto a = new A(&b.foo); auto c = new C; a.dg = &c.foo; // correctly fails to compile. } -- Derek (skype: derek.j.parnell) Melbourne, Australia 14/02/2008 4:13:59 PM |
Copyright © 1999-2021 by the D Language Foundation