iluvatar
Guest
Posts: n/a

 02-06-2007
Hi all.

I have written a 3d-vector class (for 3-dimensional space) and I have
overloaded the arihtmetic operators like +, +=, * and so on. Also, the
constructor works with doubles and has default arguments.

In my class, the operator = works for another vector (just copying the
elements), and for a double: in this cases each element of the vector
will be equal to the double. Example:

Vector3D v1;
Vector3D v2 = v1; // v2.x = v1.x, v2.y = v1.y, v2.z = v1.z

double num = 3.0;
Vector3D v2 = num; // v2.x = 3.0, v2.y = 3.0, v2.z = 3.0

Also, I have overloaded the operator *: in the case of tho vector,
like v1*v2, this is just the dot product. But when I writte
v2 = v1*num ; // it means: v2.x = (v1.x)*num, v2.y = (v1.y)*num, v2.z
= (v1.z)*num

My question is: When I have expressions like
v3 = v1*num*num2;

How can I know that I get what I want, i.e., the number num*num2
multiplying the vector v1 and then asigned to v3, and not, for
example, a temporal vector constructed with num, then a dot product
with v1, then multiplication with num2 and at last a new construction
of a vector to assign to v3?

There is some precedence in the constructor and the overloaded
operators?

Victor Bazarov
Guest
Posts: n/a

 02-06-2007
iluvatar wrote:
> I have written a 3d-vector class (for 3-dimensional space) and I have
> overloaded the arihtmetic operators like +, +=, * and so on. Also, the
> constructor works with doubles and has default arguments.
>
> In my class, the operator = works for another vector (just copying the
> elements), and for a double: in this cases each element of the vector
> will be equal to the double. Example:
>
> Vector3D v1;
> Vector3D v2 = v1; // v2.x = v1.x, v2.y = v1.y, v2.z = v1.z
>
> double num = 3.0;
> Vector3D v2 = num; // v2.x = 3.0, v2.y = 3.0, v2.z = 3.0
>
> Also, I have overloaded the operator *: in the case of tho vector,
> like v1*v2, this is just the dot product. But when I writte
> v2 = v1*num ; // it means: v2.x = (v1.x)*num, v2.y = (v1.y)*num, v2.z
> = (v1.z)*num
>
> My question is: When I have expressions like
> v3 = v1*num*num2;
>
> How can I know that I get what I want, i.e., the number num*num2
> multiplying the vector v1 and then asigned to v3, and not, for
> example, a temporal vector constructed with num, then a dot product
> with v1, then multiplication with num2 and at last a new construction
> of a vector to assign to v3?
>
> There is some precedence in the constructor and the overloaded
> operators?

Yes, there is always precedence. In the case you asked about you
get

( v3 = ( ( v1 * num ) * num2) )

That's how it's parsed and there can be no other way. It's dictated
by the language grammar. Now, every subexpression can be interpreted
differently (and that's what you seem to be concerned with).

Well, in order to invoke the operator * for two vectors when you
write 'v1 * num', the compiler has to convert 'num' to a vector first,
and to invoke the operator * for a vector and a number, there is no
conversion needed. The operation selected is the one with the fewer
conversions, in this case the multiplication with a scalar.

All those rules are actually written in the Standard (and probably
explained in some good books). I use the Standard. Those who use
books will hopefully chime in and recommend them.

V
--

Sylvester Hesp
Guest
Posts: n/a

 02-12-2007
"iluvatar" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) ups.com...
> Hi all.
>
> I have written a 3d-vector class (for 3-dimensional space) and I have
> overloaded the arihtmetic operators like +, +=, * and so on. Also, the
> constructor works with doubles and has default arguments.
>
> In my class, the operator = works for another vector (just copying the
> elements), and for a double: in this cases each element of the vector
> will be equal to the double. Example:
>
> Vector3D v1;
> Vector3D v2 = v1; // v2.x = v1.x, v2.y = v1.y, v2.z = v1.z
>
> double num = 3.0;
> Vector3D v2 = num; // v2.x = 3.0, v2.y = 3.0, v2.z = 3.0
>
> Also, I have overloaded the operator *: in the case of tho vector,
> like v1*v2, this is just the dot product. But when I writte
> v2 = v1*num ; // it means: v2.x = (v1.x)*num, v2.y = (v1.y)*num, v2.z
> = (v1.z)*num
>
> My question is: When I have expressions like
> v3 = v1*num*num2;
>
> How can I know that I get what I want, i.e., the number num*num2
> multiplying the vector v1 and then asigned to v3, and not, for
> example, a temporal vector constructed with num, then a dot product
> with v1, then multiplication with num2 and at last a new construction
> of a vector to assign to v3?
>
> There is some precedence in the constructor and the overloaded
> operators?
>
>

If you have a Vector that takes a scalar (float or double or something
similar) as argument to construct a vector with all components set to that
value, like you explained, make that constructor explicit. That way, a
Vector can never be automatically constructed out of a single scalar - you
always have to write Vector(num) instead of just num where a Vector is
expected. Of course, this disables the use of

Vector v = 3.0;

Vector v(3.0);
-or-
Vector v = Vector(3.0);

But aside from that, if you have this class:

class Vector
{
Vector(double scalar = 0.0);
float operator *(const Vector & other); // dot product
Vector operator *(double scalar); // vector multiplication
};

And this expression:

Vector v1, v2;
v1 = v2 * 3.0 * 4.0;

You can assure that the vector multiplication takes precedence over the dot
needs a conversion while Vector:perator*(double) does not)

- Sylvester

Sylvester Hesp
Guest
Posts: n/a

 02-12-2007

"Sylvester Hesp" <(E-Mail Removed)> wrote in message
news:45d052bf\$0\$324\$(E-Mail Removed)4all.nl...
> "iluvatar" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed) ups.com...
>> Hi all.
>>
>> I have written a 3d-vector class (for 3-dimensional space) and I have
>> overloaded the arihtmetic operators like +, +=, * and so on. Also, the
>> constructor works with doubles and has default arguments.
>>
>> In my class, the operator = works for another vector (just copying the
>> elements), and for a double: in this cases each element of the vector
>> will be equal to the double. Example:
>>
>> Vector3D v1;
>> Vector3D v2 = v1; // v2.x = v1.x, v2.y = v1.y, v2.z = v1.z
>>
>> double num = 3.0;
>> Vector3D v2 = num; // v2.x = 3.0, v2.y = 3.0, v2.z = 3.0
>>
>> Also, I have overloaded the operator *: in the case of tho vector,
>> like v1*v2, this is just the dot product. But when I writte
>> v2 = v1*num ; // it means: v2.x = (v1.x)*num, v2.y = (v1.y)*num, v2.z
>> = (v1.z)*num
>>
>> My question is: When I have expressions like
>> v3 = v1*num*num2;
>>
>> How can I know that I get what I want, i.e., the number num*num2
>> multiplying the vector v1 and then asigned to v3, and not, for
>> example, a temporal vector constructed with num, then a dot product
>> with v1, then multiplication with num2 and at last a new construction
>> of a vector to assign to v3?
>>
>> There is some precedence in the constructor and the overloaded
>> operators?
>>
>>

>
> If you have a Vector that takes a scalar (float or double or something
> similar) as argument to construct a vector with all components set to that
> value, like you explained, make that constructor explicit. That way, a
> Vector can never be automatically constructed out of a single scalar - you
> always have to write Vector(num) instead of just num where a Vector is
> expected. Of course, this disables the use of
>
> Vector v = 3.0;
>
> Instead, you'd have to write:
>
> Vector v(3.0);
> -or-
> Vector v = Vector(3.0);
>
> But aside from that, if you have this class:
>
> class Vector
> {
> Vector(double scalar = 0.0);
> float operator *(const Vector & other); // dot product
> Vector operator *(double scalar); // vector multiplication
> };
>
> And this expression:
>
> Vector v1, v2;
> v1 = v2 * 3.0 * 4.0;
>
> You can assure that the vector multiplication takes precedence over the
> Vector&) needs a conversion while Vector:perator*(double) does not)
>
> - Sylvester

As to what is better from a design-perspective, I think it's better to make
the constructor explicit like I explained. Because scalars aren't vectors,
therefore you shouldn't be able to use a scalar in a place where a vector is
expected, unless you want to explicitely create a vector using that scalar

- Sylvester