www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - *final* class member (D2)

reply Denton Cockburn <diboss hotmail.com> writes:
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
}
Feb 13 2008
next sibling parent reply Denton Cockburn <diboss hotmail.com> writes:
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.
 
 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
 }

formatting issues: (const doesn't work) real delegate() dg; // this is that function; should be: (const doesn't work) real delegate() dg; // this is that function
Feb 13 2008
next sibling parent reply Robert Fraser <fraserofthenight gmail.com> writes:
Denton Cockburn wrote:
 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.

 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
 }

formatting issues: (const doesn't work) real delegate() dg; // this is that function; should be: (const doesn't work) real delegate() dg; // this is that function

Use "final" :-)
Feb 13 2008
parent reply Robert Fraser <fraserofthenight gmail.com> writes:
Robert Fraser wrote:
 Denton Cockburn wrote:
 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.

 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
 }

formatting issues: (const doesn't work) real delegate() dg; // this is that function; should be: (const doesn't work) real delegate() dg; // this is that function

Use "final" :-)

Oops, I thought you meant member function. AFAIK, there's no way to do that for a member variable.
Feb 13 2008
parent reply Jason House <jason.james.house gmail.com> writes:
Robert Fraser Wrote:

 Robert Fraser wrote:
 Denton Cockburn wrote:
 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.

 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
 }

formatting issues: (const doesn't work) real delegate() dg; // this is that function; should be: (const doesn't work) real delegate() dg; // this is that function

Use "final" :-)

Oops, I thought you meant member function. AFAIK, there's no way to do that for a member variable.

I thought member variables with a const storage class could be initialized in the constructor. I thought it was possible to do stuff like: class X{ const int a; this(int b){ a = b; } } Am I wrong about that? If not, why can't this apply to delegates? Could it be confusion about return type verses const storage class? If that's the problem, enclosing with const{} could solve the problem...
Feb 13 2008
parent Denton Cockburn <diboss hotmail.com> writes:
On Wed, 13 Feb 2008 15:50:39 -0500, Jason House wrote:

 Robert Fraser Wrote:
 
 Robert Fraser wrote:
 Denton Cockburn wrote:
 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.

 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
 }

formatting issues: (const doesn't work) real delegate() dg; // this is that function; should be: (const doesn't work) real delegate() dg; // this is that function

Use "final" :-)

Oops, I thought you meant member function. AFAIK, there's no way to do that for a member variable.

I thought member variables with a const storage class could be initialized in the constructor. I thought it was possible to do stuff like: class X{ const int a; this(int b){ a = b; } } Am I wrong about that? If not, why can't this apply to delegates? Could it be confusion about return type verses const storage class? If that's the problem, enclosing with const{} could solve the problem...

I would have thought I would've been able to use const as well. I got an error when I did it. the const applies as: const(real delegate()) dg - but it doesn't affect the ability to reassign the variable. It gave errors when I tried to assign it to the delegate parameter (&b.foo) because &b.foo was a real delegate(), and not a const(real delegate()).
Feb 13 2008
prev sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Wed, 13 Feb 2008 17:07:47 +0100, Denton Cockburn <diboss hotmail.com>=
  =

wrote:

 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 need=


 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 =3D dg; }
 }

 class B
 {
    real foo() { return 3.5; }
 }

 class C
 {
    real foo() { return 4.5; }
 }

 void main()
 {
    auto b =3D new B;
    auto a =3D new A(&b.foo);
    auto c =3D new C;
    a.fitness =3D &c.foo; // I want this to be an error
 }

formatting issues: (const doesn't work) real delegate() dg; // this is that function; should be: (const doesn't work) real delegate() dg; // this is that function

You could make the delegate private, and use a function to call it. class A { private: real delegate() m_dg; public: real dg() { return m_dg(); } this(real delegate() _dg) { m_dg =3D _dg; } } Of course, private in D only means module-private, so whoever makes = changes to the module might still break things, but for anyone just = importing it, the problem should be gone.
Feb 13 2008
prev sibling next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"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
Feb 13 2008
parent reply Denton Cockburn <diboss hotmail.com> writes:
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.
Feb 13 2008
parent reply "Neil Vice" <sardonicpresence gmail.com> writes:
"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
Feb 13 2008
parent reply Denton Cockburn <diboss hotmail.com> writes:
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.
Feb 13 2008
parent "Neil Vice" <sardonicpresence gmail.com> writes:
"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.
Feb 13 2008
prev sibling parent Derek Parnell <derek nomail.afraid.org> writes:
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
Feb 13 2008