Question about overloaded operators and constructors

Discussion in 'C++' started by iluvatar, Feb 6, 2007.

  1. iluvatar

    iluvatar Guest

    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?

    Thanks in advance.
    iluvatar, Feb 6, 2007
    #1
    1. Advertising

  2. 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
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Feb 6, 2007
    #2
    1. Advertising

  3. "iluvatar" <> wrote in message
    news:...
    > 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?
    >
    > Thanks in advance.
    >


    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 dot
    product according to the overloading rules (Vector::eek:perator*(const Vector&)
    needs a conversion while Vector::eek:perator*(double) does not)

    - Sylvester
    Sylvester Hesp, Feb 12, 2007
    #3
  4. "Sylvester Hesp" <> wrote in message
    news:45d052bf$0$324$4all.nl...
    > "iluvatar" <> wrote in message
    > news:...
    >> 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?
    >>
    >> Thanks in advance.
    >>

    >
    > 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
    > dot product according to the overloading rules (Vector::eek:perator*(const
    > Vector&) needs a conversion while Vector::eek: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
    Sylvester Hesp, Feb 12, 2007
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    1
    Views:
    523
    Victor Bazarov
    Feb 7, 2005
  2. George Economos
    Replies:
    4
    Views:
    339
    Victor Bazarov
    Aug 23, 2005
  3. Riku Jarvinen
    Replies:
    5
    Views:
    412
    Thomas J. Gritzan
    Oct 26, 2005
  4. Jeremy Smith
    Replies:
    2
    Views:
    575
    Jeremy Smith
    Aug 3, 2006
  5. Jess
    Replies:
    5
    Views:
    586
    Ron Natalie
    Jun 7, 2007
Loading...

Share This Page