digitalmars.D - My story of C++ vs. D and trying to return classes by value
- Michael Coupland <mcoupland hmc.edu> May 19 2004
- Norbert Nemec <Norbert.Nemec gmx.de> May 20 2004
- Michael Coupland <mcoupland hmc.edu> May 20 2004
- Andy Friesen <andy ikagames.com> May 20 2004
So I was porting my C++ vector code to D in preparation for my first big
D project, and I ran into the following problem: I have overloaded * and
*= scalar multiplication operations for the vector class, and I would
prefer to write *= in terms of *. However, I tried copying my C++ code,
which resulted in the following (broken) D code:
// BROKEN
class Vec2( ScalarType )
{
// ... code ...
////////////////////////////////////
// Overloaded * and *=
Vec2 opMul( ScalarType s )
{
return new Vec2( x*s, y*s );
}
Vec2 opMulAssign( ScalarType s )
{
this = this * s;
return this;
}
}
I tried compiling, and *= didn't seem to be working. In retrospect, it
was a silly coding error: I'm overwriting the this pointer in
opMulAssign(), which was resulting in some of that good ol' "undefined"
behavior. As I was typing up a complaint/help request to this board, I
realized that there was an interesting solution: do it the other way! So
I wrote * in terms of *= and got the following (working) code:
// WORKS!
class Vec2( ScalarType )
{
// ... code ...
////////////////////////////////////
// Overloaded * and *=
Vec2 opMul( ScalarType s )
{
Vec2 res = new Vec2(this);
res *= s;
return res;
}
Vec2 opMulAssign( ScalarType s )
{
x *= s;
y *= s;
return this;
}
}
It just goes to show that you need to be careful when you're used to
C++. I'm still trying to get my D-legs under me, and I figured that this
might be a helpful story for others who are still beginning with D.
Michael Coupland
May 19 2004
You would probably want to use struct instead of class. A struct is always handled by value. Michael Coupland wrote:So I was porting my C++ vector code to D in preparation for my first big D project, and I ran into the following problem: I have overloaded * and *= scalar multiplication operations for the vector class, and I would prefer to write *= in terms of *. However, I tried copying my C++ code, which resulted in the following (broken) D code: // BROKEN class Vec2( ScalarType ) { // ... code ... //////////////////////////////////// // Overloaded * and *= Vec2 opMul( ScalarType s ) { return new Vec2( x*s, y*s ); } Vec2 opMulAssign( ScalarType s ) { this = this * s; return this; } } I tried compiling, and *= didn't seem to be working. In retrospect, it was a silly coding error: I'm overwriting the this pointer in opMulAssign(), which was resulting in some of that good ol' "undefined" behavior. As I was typing up a complaint/help request to this board, I realized that there was an interesting solution: do it the other way! So I wrote * in terms of *= and got the following (working) code: // WORKS! class Vec2( ScalarType ) { // ... code ... //////////////////////////////////// // Overloaded * and *= Vec2 opMul( ScalarType s ) { Vec2 res = new Vec2(this); res *= s; return res; } Vec2 opMulAssign( ScalarType s ) { x *= s; y *= s; return this; } } It just goes to show that you need to be careful when you're used to C++. I'm still trying to get my D-legs under me, and I figured that this might be a helpful story for others who are still beginning with D. Michael Coupland
May 20 2004
Norbert Nemec wrote:You would probably want to use struct instead of class. A struct is always handled by value.
I thought about doing that, but I was a little hesitant because I wouldn't be able to have: this( ScalarType s ) { x = s; y = s; } But in retrospect, using a struct is a 'more correct' choice (vectors are simple aggregates). I don't particularly use that constructor anyway, but I'd appreciate a suggestion on how to recreate the following (C++) typedef Vec2<float> Vec2f; Vec2f test_vec( 1, 2 ); I don't know how to do something like this without constructors similar to the one above. I know that /static/ structs can be initialized as: static Vec2f test_vec = { 1, 2 }; which would be fine for me, except that it doesn't work for non-static variables. Any suggestions? Michael Coupland
May 20 2004
Michael Coupland wrote:I'd appreciate a suggestion on how to recreate the following (C++) typedef Vec2<float> Vec2f; Vec2f test_vec( 1, 2 ); I don't know how to do something like this without constructors similar to the one above. I know that /static/ structs can be initialized as: static Vec2f test_vec = { 1, 2 }; which would be fine for me, except that it doesn't work for non-static variables. Any suggestions?
You can come close by defining a static opCall method that returns a Vector to get this: Vector v = Vector(1,2,3); I think it's ugly and evil, but you could also make a nonstatic opCall that makes the vector mutate and return itself: Vector v; v(1,2,3); -- andy
May 20 2004








Andy Friesen <andy ikagames.com>