overloading operators (basic)

P

pauldepstein

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
 
B

Ben Pope

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
 
D

deane_gavin

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
 
M

Marcus Kwok

Ben Pope said:
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 */)
{
/* ... */
}
 
D

deane_gavin

Marcus said:
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
 
M

Marcus Kwok

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.
 
J

Jacek Dziedzic

Ben said:
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.
 
D

deane_gavin

Jacek said:
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
 
J

Jacek Dziedzic

(e-mail address removed) wrote
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.
 
?

=?ISO-8859-15?Q?Juli=E1n?= Albo

Jacek said:
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) { }
 
B

Ben Pope

Jacek said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top