|
Archives
D Programming
digitalmars.D
digitalmars.D.bugs
digitalmars.D.dtl
digitalmars.D.ide
digitalmars.D.dwt
digitalmars.D.announce
digitalmars.D.learn
digitalmars.D.debugger
D.gnu
D
C/C++ Programming
c++
c++.announce
c++.atl
c++.beta
c++.chat
c++.command-line
c++.dos
c++.dos.16-bits
c++.dos.32-bits
c++.idde
c++.mfc
c++.rtl
c++.stl
c++.stl.hp
c++.stl.port
c++.stl.sgi
c++.stlsoft
c++.windows
c++.windows.16-bits
c++.windows.32-bits
c++.wxwindows
digitalmars.empire
digitalmars.DMDScript
electronics
|
digitalmars.D.learn - struct and class member alias
In the following, the aliases have no apparent effect (although they do
compile). Is there a way to achieve a similar effect? I just want to be able to
access
boxInstance.pos.x
using
boxInstance.x
I got the alias idea from the function page in the documentation:
http://digitalmars.com/d/function.html
under Function Inheritance and Overloading
obviously it doesn't describe the same thing, but I figured I'd give it a shot.
Given that it doesn't seem to work I was thinking that it might be a handy
feature to have in the language?
I tried this as a struct(suitably modified) also.
public class Coord
{
int x, y;
this
(in int x, in int y)
{
this.x = x;
this.y = y;
}
}
public class Box
{
Coord pos, size;
alias pos.x x;
alias pos.y y;
alias size.x w;
alias size.y h;
this
(in int x, in int y,
in int w, in int h)
{
pos = new Coord(x, y);
size = new Coord(w, h);
}
}
"Stuart Murray" <stuart.w.murray fakey.nospambots.gmail.com> wrote in
message news:f4430d$14oc$1 digitalmars.com...
In the following, the aliases have no apparent effect (although they do
compile). Is there a way to achieve a similar effect? I just want to be
able to access
boxInstance.pos.x
using
boxInstance.x
It doesn't compile; I get
foo.d(19): Error: pos.x is used as a type
foo.d(20): Error: pos.y is used as a type
foo.d(21): Error: size.x is used as a type
foo.d(22): Error: size.y is used as a type
It's no surprise, either. You're not allowed to make aliases of
expressions.
What you can do is make "properties." You have a setter and a getter for
each property. Because of some syntactic sugar, you can write "a.x" to mean
"a.x()" and "a.x = 5" to mean "a.x(5)".
Here's the Box class with read/write properties for x and y defined.
public class Box
{
Coord pos, size;
this(in int x, in int y, in int w, in int h)
{
pos = new Coord(x, y);
size = new Coord(w, h);
}
public int x()
{
return pos.x;
}
public void x(int val)
{
pos.x = val;
}
public int y()
{
return pos.y;
}
public void y(int val)
{
pos.y = val;
}
}
It's a little more verbose than you might like.
Another solution would be to make public reference fields in Box that refer
to the inner pos.x, pos.y etc. members. But D doesn't have generic
reference types, so foo :(
Jarrett Billingsley Wrote:
"Stuart Murray" <stuart.w.murray fakey.nospambots.gmail.com> wrote in
message news:f4430d$14oc$1 digitalmars.com...
In the following, the aliases have no apparent effect (although they do
compile). Is there a way to achieve a similar effect? I just want to be
able to access
boxInstance.pos.x
using
boxInstance.x
It doesn't compile; I get
foo.d(19): Error: pos.x is used as a type
foo.d(20): Error: pos.y is used as a type
foo.d(21): Error: size.x is used as a type
foo.d(22): Error: size.y is used as a type
It's no surprise, either. You're not allowed to make aliases of
expressions.
What you can do is make "properties." You have a setter and a getter for
each property. Because of some syntactic sugar, you can write "a.x" to mean
"a.x()" and "a.x = 5" to mean "a.x(5)".
Here's the Box class with read/write properties for x and y defined.
public class Box
{
Coord pos, size;
this(in int x, in int y, in int w, in int h)
{
pos = new Coord(x, y);
size = new Coord(w, h);
}
public int x()
{
return pos.x;
}
public void x(int val)
{
pos.x = val;
}
public int y()
{
return pos.y;
}
public void y(int val)
{
pos.y = val;
}
}
It's a little more verbose than you might like.
Another solution would be to make public reference fields in Box that refer
to the inner pos.x, pos.y etc. members. But D doesn't have generic
reference types, so foo :(
Interesting that it doesn't compile for you.. It definitely does for me (using
DMD v1.014)
This is the example I referred to, if anyones interested:
class A
{
int foo(int x) { ... }
int foo(long y) { ... }
}
class B : A
{
alias A.foo foo;
override int foo(long x) { ... }
}
Its in the documentation. As I said, it's slightly different thing, but it
seems to .. *match*..
It is unfortunate to not have reference types a la C++, but I love D in almost
every other way :)
"Stuart Murray" <stuart.w.murray fakey.nospambots.gmail.com> wrote in
message news:f458q0$2vea$1 digitalmars.com...
Interesting that it doesn't compile for you.. It definitely does for me
(using DMD v1.014)
This is the example I referred to, if anyones interested:
class A
{
int foo(int x) { ... }
int foo(long y) { ... }
}
class B : A
{
alias A.foo foo;
override int foo(long x) { ... }
}
Its in the documentation. As I said, it's slightly different thing, but it
seems to .. *match*..
Oh, well _that_ will compile :) It's because "A.foo" is not an expression,
it's a symbol. You're saying "bring my superclass's implementation of foo
into this namespace so it can be overloaded." A.foo is a name, so you can
alias it. The "A." is just there as a marker to say where foo lives.
In your example, pos and size are class instances; they have no meaning
until they've been new'ed. Furthermore, pos.x is not a symbol, it's an
expression -- it's an access to a member whose location can't be determined
at compile time. So, you can't alias it.
Jarrett Billingsley Wrote:
"Stuart Murray" <stuart.w.murray fakey.nospambots.gmail.com> wrote in
message news:f458q0$2vea$1 digitalmars.com...
Interesting that it doesn't compile for you.. It definitely does for me
(using DMD v1.014)
This is the example I referred to, if anyones interested:
class A
{
int foo(int x) { ... }
int foo(long y) { ... }
}
class B : A
{
alias A.foo foo;
override int foo(long x) { ... }
}
Its in the documentation. As I said, it's slightly different thing, but it
seems to .. *match*..
Oh, well _that_ will compile :) It's because "A.foo" is not an expression,
it's a symbol. You're saying "bring my superclass's implementation of foo
into this namespace so it can be overloaded." A.foo is a name, so you can
alias it. The "A." is just there as a marker to say where foo lives.
In your example, pos and size are class instances; they have no meaning
until they've been new'ed. Furthermore, pos.x is not a symbol, it's an
expression -- it's an access to a member whose location can't be determined
at compile time. So, you can't alias it.
Thanks, that all seems to make sense. Thanks a lot for your help.
As a last note I would suggest that the example:
class A
{
int foo(int x) { ... }
int foo(long y) { ... }
}
class B : A
{
alias A.foo foo;
override int foo(long x) { ... }
}
seems a bit of a hacky way to fix the overload choosing thing, I suspect most
newcomers would assume that subclass member functions would overload with
superclass members of the same name. But such is life.
"Stuart Murray" <stuart.w.murray fakey.nospambots.gmail.com> wrote in
message news:f46eg2$1qce$1 digitalmars.com...
Thanks, that all seems to make sense. Thanks a lot for your help.
As a last note I would suggest that the example:
class A
{
int foo(int x) { ... }
int foo(long y) { ... }
}
class B : A
{
alias A.foo foo;
override int foo(long x) { ... }
}
seems a bit of a hacky way to fix the overload choosing thing, I suspect
most newcomers would assume that subclass member functions would overload
with superclass members of the same name. But such is life.
_Everyone_ does. But "this is the way C++ does it," as if that means
anything. *sigh*
|
|