overloading operators (basic)

Discussion in 'C++' started by pauldepstein@att.net, Dec 6, 2005.

  1. Guest

    Is it o.k. (from the point of view of both style and legality) for
    functions to call on overloaded versions of themselves?

    For example, I want to be able to do two things to my object which is
    called node.

    I want to be able to assign coordinates to it where the coordinates
    correspond to specific integers; I also want coordinates assigned
    based on the intrinsic properties of the node (independent of any other
    specific integers.)

    So I have code void set_coords( int x_coord, int y_coord)
    {

    }


    Can I then introduce code

    void set_coords()
    { int x;
    int y;
    x = .........;
    y = ...;
    set_coords(x, y);
    } ?

    My apologies if this sort of thing is done all the time -- as a novice,
    I've never seen it.

    If someone wants to say "Well, go ahead and try it!", then please note
    that I also need to know whether this is considered o.k. from a style
    perspective. It's obviously important to use clear conventions that
    don't confuse others.

    Thank you,

    Paul Epstein
     
    , Dec 6, 2005
    #1
    1. Advertising

  2. Ben Pope Guest

    wrote:
    > Is it o.k. (from the point of view of both style and legality) for
    > functions to call on overloaded versions of themselves?


    Yes.

    > For example, I want to be able to do two things to my object which is
    > called node.
    >
    > I want to be able to assign coordinates to it where the coordinates
    > correspond to specific integers; I also want coordinates assigned
    > based on the intrinsic properties of the node (independent of any other
    > specific integers.)
    >
    > So I have code void set_coords( int x_coord, int y_coord)
    > {
    >
    > }
    >
    >
    > Can I then introduce code
    >
    > void set_coords()
    > { int x;
    > int y;
    > x = .........;
    > y = ...;
    > set_coords(x, y);
    > } ?


    Yes, but prefer:

    void set_coords() {
    int x = /* ... */
    int y = /* ... */;
    set_coords(x, y);
    }

    No need to declare x and y before assigning to them.

    > My apologies if this sort of thing is done all the time -- as a novice,
    > I've never seen it.
    >
    > If someone wants to say "Well, go ahead and try it!", then please note
    > that I also need to know whether this is considered o.k. from a style
    > perspective. It's obviously important to use clear conventions that
    > don't confuse others.


    It's perfectly acceptable.

    Just don't try to do it with constructors, it won't achieve what you want.

    Ben Pope
    --
    I'm not just a number. To many, I'm known as a string...
     
    Ben Pope, Dec 6, 2005
    #2
    1. Advertising

  3. Guest

    wrote:
    > Is it o.k. (from the point of view of both style and legality) for
    > functions to call on overloaded versions of themselves?


    Legality is easy: yes it's perfectly legal.

    > For example, I want to be able to do two things to my object which is
    > called node.
    >
    > I want to be able to assign coordinates to it where the coordinates
    > correspond to specific integers; I also want coordinates assigned
    > based on the intrinsic properties of the node (independent of any other
    > specific integers.)


    It's difficult to say without knowing more about your design, but my
    first reaction to this is that it sounds like two conceptually
    different operations that are not best described by the same name.

    > So I have code void set_coords( int x_coord, int y_coord)
    > {
    >
    > }
    >
    >
    > Can I then introduce code
    >
    > void set_coords()
    > { int x;
    > int y;
    > x = .........;
    > y = ...;
    > set_coords(x, y);
    > } ?


    Are these two set_coords overloads are members of your node class?

    > My apologies if this sort of thing is done all the time -- as a novice,
    > I've never seen it.
    >
    > If someone wants to say "Well, go ahead and try it!", then please note
    > that I also need to know whether this is considered o.k. from a style
    > perspective. It's obviously important to use clear conventions that
    > don't confuse others.


    Clarity extends further than the structure of your code. You also need
    clarity in design. If your design has the same conceptual operation
    that needs to be called in two different ways, then what you've got in
    fine.

    But if those two operations are conceptually different, they should be
    made available through appropriately named functions in your class's
    interface. That they may both use some common functionality is an
    implementation detail that should be hidden from the users of your
    class. So something like

    class node_t
    {
    public:
    // This one used to be set_coord(int, int)
    void move_node(int x_coord, int y_coord);

    // This one used to be set_coord()
    void position_intrinsically();

    private:
    void set_coords(int x_coord, int y_coord);
    int x_;
    int y_;
    };

    void node_t::move_node(int x_coord, int y_coord)
    {
    set_coords(x_coord, y_coord);
    }

    void node_t::position_intrinsically()
    {
    int x = ... // Whatever you did in set_coords() before
    int y = ... // Whatever you did in set_coords() before
    set_coords(x, y);
    }

    void node_t::set_coords(int x_coord, int y_coord)
    {
    x_ = x_coord;
    y_ = y_coord;
    }

    So, if I have a node_t object, I know I can move it to a position with
    move_node and I can position it intrinsically with
    position_intrinsically. Two different operations with appropriate names
    that I call in the appropriate way. The fact that internally, both
    operations end up calling a set_coords function to change the
    coordinates of the node is an implementation detail I don't care about
    and I don't have to see.

    Now you have an object that knows intrinsically where to position
    itself, and yet allows me to position it anywhere I choose. Only you
    know your design and it's up to you to decide whether that makes sense
    or not.

    Gavin Deane
     
    , Dec 6, 2005
    #3
  4. Marcus Kwok Guest

    Ben Pope <> wrote:
    > wrote:
    >> void set_coords()
    >> { int x;
    >> int y;
    >> x = .........;
    >> y = ...;
    >> set_coords(x, y);
    >> } ?

    >
    > Yes, but prefer:
    >
    > void set_coords() {
    > int x = /* ... */
    > int y = /* ... */;
    > set_coords(x, y);
    > }
    >
    > No need to declare x and y before assigning to them.


    Just looking at this, default function arguments also might do what the
    OP wanted too:

    void set_coords(int x = /* default x */, int y = /* default y */)
    {
    /* ... */
    }

    --
    Marcus Kwok
     
    Marcus Kwok, Dec 6, 2005
    #4
  5. Guest

    Marcus Kwok wrote:
    > Ben Pope <> wrote:
    > > wrote:
    > >> void set_coords()
    > >> { int x;
    > >> int y;
    > >> x = .........;
    > >> y = ...;
    > >> set_coords(x, y);
    > >> } ?

    > >
    > > Yes, but prefer:
    > >
    > > void set_coords() {
    > > int x = /* ... */
    > > int y = /* ... */;
    > > set_coords(x, y);
    > > }
    > >
    > > No need to declare x and y before assigning to them.

    >
    > Just looking at this, default function arguments also might do what the
    > OP wanted too:
    >
    > void set_coords(int x = /* default x */, int y = /* default y */)
    > {
    > /* ... */
    > }


    Now you have three different overloads. The OP only has these two

    set_coords(int, int)
    set_coords()

    The default parameters solution allows

    set_coords(int)

    where x is passed in and y is defaulted.

    Unless you want to provide that way of calling set_coords, I would not
    use default parameters for this.

    Gavin Deane
     
    , Dec 6, 2005
    #5
  6. Marcus Kwok Guest

    >> > wrote:
    >> >> void set_coords()
    >> >> { int x;
    >> >> int y;
    >> >> x = .........;
    >> >> y = ...;
    >> >> set_coords(x, y);
    >> >> } ?


    >> Ben Pope <> wrote:
    >> > Yes, but prefer:
    >> >
    >> > void set_coords() {
    >> > int x = /* ... */
    >> > int y = /* ... */;
    >> > set_coords(x, y);
    >> > }
    >> >
    >> > No need to declare x and y before assigning to them.


    > Marcus Kwok wrote:
    >> Just looking at this, default function arguments also might do what the
    >> OP wanted too:
    >>
    >> void set_coords(int x = /* default x */, int y = /* default y */)
    >> {
    >> /* ... */
    >> }


    wrote:
    > Now you have three different overloads. The OP only has these two
    >
    > set_coords(int, int)
    > set_coords()
    >
    > The default parameters solution allows
    >
    > set_coords(int)
    >
    > where x is passed in and y is defaulted.


    Ahh, thanks, I forgot about this case.

    --
    Marcus Kwok
     
    Marcus Kwok, Dec 6, 2005
    #6
  7. Ben Pope wrote:
    > It's perfectly acceptable.
    >
    > Just don't try to do it with constructors, it won't achieve what you want.


    but variant A is fine, right?

    // --- variant A
    Foo::Foo(int a) {};
    Foo::Foo() : Foo(3) {};
    // --- variant B
    Foo::Foo(int a) {};
    Foo::Foo() {Foo(3);}

    is fine, right?

    - J.
     
    Jacek Dziedzic, Dec 7, 2005
    #7
  8. Guest

    Jacek Dziedzic wrote:
    > Ben Pope wrote:
    > > It's perfectly acceptable.
    > >
    > > Just don't try to do it with constructors, it won't achieve what you want.

    >
    > but variant A is fine, right?
    >
    > // --- variant A
    > Foo::Foo(int a) {};
    > Foo::Foo() : Foo(3) {};
    > // --- variant B
    > Foo::Foo(int a) {};
    > Foo::Foo() {Foo(3);}
    >
    > is fine, right?


    If you mean

    class Foo
    {
    public:
    Foo();
    explicit Foo(int);
    };

    Foo::Foo(int a) {}
    Foo::Foo() : Foo(3) {} // This will not compile

    then, no you can't do that.

    [Making the single argument constructor explicit has nothing to do with
    your question, but it's generally a good idea unless you *want* implict
    conversion from int to Foo, so I've done it]

    In this case a default value for a would do what you want.

    class Foo
    {
    public:
    explicit Foo(int);
    };

    Foo::Foo(int a = 3) {}

    But note my comment elsethread about why defaulting all the parameter
    values is not generally appropriate when you have more than one
    parameter.

    More generally you would do

    class Foo
    {
    public:
    Foo();
    Foo(int, int);
    private:
    void init(int, int);
    };

    Foo::Foo() { init(3, 42); }
    Foo::Foo(int a, int b) { init(a, b); }

    and implement the init function appropriately.

    Gavin Deane
     
    , Dec 7, 2005
    #8
  9. wrote
    > Jacek Dziedzic wrote:
    >
    >>Ben Pope wrote:
    >>
    >>>It's perfectly acceptable.
    >>>
    >>>Just don't try to do it with constructors, it won't achieve what you want.

    >>
    >>but variant A is fine, right?
    >>
    >>// --- variant A
    >>Foo::Foo(int a) {};
    >>Foo::Foo() : Foo(3) {};
    >>// --- variant B
    >>Foo::Foo(int a) {};
    >>Foo::Foo() {Foo(3);}
    >>
    >>is fine, right?

    >
    >
    > If you mean
    >
    > class Foo
    > {
    > public:
    > Foo();
    > explicit Foo(int);
    > };
    >
    > Foo::Foo(int a) {}
    > Foo::Foo() : Foo(3) {} // This will not compile
    >
    > then, no you can't do that.


    Aaaah, works for base class only, I forgot that again!

    > [Making the single argument constructor explicit has nothing to do with
    > your question, but it's generally a good idea unless you *want* implict
    > conversion from int to Foo, so I've done it]


    Sure.

    > In this case a default value for a would do what you want.
    >
    > class Foo
    > {
    > public:
    > explicit Foo(int);
    > };
    >
    > Foo::Foo(int a = 3) {}


    Sure.

    >
    > But note my comment elsethread about why defaulting all the parameter
    > values is not generally appropriate when you have more than one
    > parameter.


    Yep, you then half-willingly add constructors for a smaller
    number of parameters.

    > More generally you would do
    >
    > class Foo
    > {
    > public:
    > Foo();
    > Foo(int, int);
    > private:
    > void init(int, int);
    > };
    >
    > Foo::Foo() { init(3, 42); }
    > Foo::Foo(int a, int b) { init(a, b); }
    >
    > and implement the init function appropriately.


    yes, I even started a thread on this a few days ago.
    The drawback is init() can't use initialization lists.

    thanks for the clarification,
    - J.
     
    Jacek Dziedzic, Dec 7, 2005
    #9
  10. Jacek Dziedzic wrote:

    >> More generally you would do
    >>
    >> class Foo
    >> {
    >> public:
    >> Foo();
    >> Foo(int, int);
    >> private:
    >> void init(int, int);
    >> };
    >>
    >> Foo::Foo() { init(3, 42); }
    >> Foo::Foo(int a, int b) { init(a, b); }
    >>
    >> and implement the init function appropriately.

    >
    > yes, I even started a thread on this a few days ago.
    > The drawback is init() can't use initialization lists.


    You can use a base class:

    class Foo : private FooBase { ... };

    Foo::Foo () : FooBase (3, 42) { }
    Foo::Foo (int a, int b) : FooBase (a, b) { }

    --
    Salu2
     
    =?ISO-8859-15?Q?Juli=E1n?= Albo, Dec 7, 2005
    #10
  11. Ben Pope Guest

    Jacek Dziedzic wrote:
    > Ben Pope wrote:
    >> It's perfectly acceptable.
    >>
    >> Just don't try to do it with constructors, it won't achieve what you
    >> want.

    >
    > but variant A is fine, right?
    >
    > // --- variant A
    > Foo::Foo(int a) {};
    > Foo::Foo() : Foo(3) {};
    > // --- variant B
    > Foo::Foo(int a) {};
    > Foo::Foo() {Foo(3);}
    >
    > is fine, right?


    I don't see how it would be, are you referring to:

    class Foo {
    public:
    Foo(int a) : a_(a) {}
    Foo() : Foo(3) {}
    private:
    int a_;
    };

    int main() {
    Foo foo;
    }

    Foo is not a base or member of itself, so I'm not sure what you are
    intending to initialise.

    Ben Pope
    --
    I'm not just a number. To many, I'm known as a string...
     
    Ben Pope, Dec 9, 2005
    #11
    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. Ron Natalie
    Replies:
    0
    Views:
    406
    Ron Natalie
    Jul 9, 2003
  2. C Wood
    Replies:
    4
    Views:
    1,017
    Stuart Golodetz
    Jul 10, 2003
  3. B.R.Kumar

    overloading operators

    B.R.Kumar, Oct 10, 2003, in forum: C++
    Replies:
    2
    Views:
    343
    rossum
    Oct 10, 2003
  4. Zenon
    Replies:
    6
    Views:
    452
    =?ISO-8859-1?Q?Christian_Brechb=FChler?=
    Oct 25, 2003
  5. Nimmi Srivastav

    Overloading new and delete operators

    Nimmi Srivastav, Jan 31, 2004, in forum: C++
    Replies:
    3
    Views:
    2,693
    John Harrison
    Feb 2, 2004
Loading...

Share This Page