overriding the + operator

M

Michael

Hi,

As an exercise, I created a class C that duplicates a value x
thus having x_val1 and x_val2
I also overrided the + operator so that
if I have z = x + y (x,y and z belong class C) then
+ performs z_val1 = x_val1 + y_val1
z_val2 = x_val2 + y_val2

This works fine but it doesn't allow more than one addition per
equation
ex z = x + y + t (x,y,z and t belong to C)

Can someone please enlighten me how can I do it ?

This is the code I wrote
///////////////////////////////////////////////////////////////////////////////
class Cfloat {
//Creates 2 replicas of a variable.
private:
float _r1; //first replica
float _r2; //second replica
public:
float r1() { return _r1; }
float r2() { return _r2; }
Cfloat(const float x) : _r1(x), _r2(x) {}
friend Cfloat operator +(const Cfloat &,const Cfloat &);
};

Cfloat operator +(Cfloat &op1,Cfloat &op2)
{
float CorrectValue;
float r1 = op1.r1() + op2.r1(),
r2 = op1.r2() + op2.r2();
... {pick one}
return(Cfloat(PickedValue));
}

int main
{
....
Cfloat result;
result = a + b;
result = a + b + c; // If there is more than one operator then the
program errors :(
}
///////////////////////////////////////////////////////////////////////////////

TIA
Michal
 
S

Swampmonster

Michael said:
Hi,

As an exercise, I created a class C that duplicates a value x
thus having x_val1 and x_val2
I also overrided the + operator so that
if I have z = x + y (x,y and z belong class C) then
+ performs z_val1 = x_val1 + y_val1
z_val2 = x_val2 + y_val2

This works fine but it doesn't allow more than one addition per
equation
ex z = x + y + t (x,y,z and t belong to C)

Can someone please enlighten me how can I do it ?

This is the code I wrote
///////////////////////////////////////////////////////////////////////////////
class Cfloat {
//Creates 2 replicas of a variable.
private:
float _r1; //first replica
float _r2; //second replica
public:
float r1() { return _r1; }
float r2() { return _r2; }
Cfloat(const float x) : _r1(x), _r2(x) {}
friend Cfloat operator +(const Cfloat &,const Cfloat &);
};

Cfloat operator +(Cfloat &op1,Cfloat &op2)
{
float CorrectValue;
float r1 = op1.r1() + op2.r1(),
r2 = op1.r2() + op2.r2();
... {pick one}
return(Cfloat(PickedValue));
}

int main
{
...
Cfloat result;
result = a + b;
result = a + b + c; // If there is more than one operator then the
program errors :(
}
///////////////////////////////////////////////////////////////////////////////

TIA
Michal

You have some errors in your code. #1 the "const" on the arguments to
the "operator +" is missing, and if you put it in then you can't access
functions f1() and f2() anymore because they're not const. So if you
then put make f1() and f2() const too (which should be no problem), then
everything compiles just fine. If not you might have a broken compiler.
And: do not use prefix "_" - use postfix "m_" for members. Prefix "_" is
reserved for implementation-details.

So this works just nice:

class Cfloat {
//Creates 2 replicas of a variable.
private:
float m_r1; //first replica
float m_r2; //second replica
public:
float r1() const { return m_r1; }
float r2() const { return m_r2; }
Cfloat(const float x) : m_r1(x), m_r2(x) {}
friend Cfloat operator +(const Cfloat &,const Cfloat &);
};

Cfloat operator +(const Cfloat &op1,const Cfloat &op2)
{
float CorrectValue;
float r1 = op1.r1() + op2.r1();
float r2 = op1.m_r2 + op2.m_r2; // since it's friend that works too
CorrectValue = r2; // whatever

return(Cfloat(CorrectValue));
}

void foo()
{
Cfloat a(1),b(2),c(3);
Cfloat result=a+b+c;
}
 
I

Ingo Nolden

You have some errors in your code. #1 the "const" on the arguments to
the "operator +" is missing, and if you put it in then you can't access
functions f1() and f2() anymore because they're not const. So if you
then put make f1() and f2() const too (which should be no problem), then
everything compiles just fine. If not you might have a broken compiler.
And: do not use prefix "_" - use postfix "m_" for members. Prefix "_" is
reserved for implementation-details.

Hi Swamp,

this is interesting. I always though its a matter of taste. Is it some
guidelines that tell it?

So I found that my STL is using the "_" prefix ( dinkumware ) everywhere
I looked in. I liked that much better than "m_" prefix ( it is not
postfix I think, as it stands BEFORE the actual name ) because I use
autocomplete features and have a nicer ordering that way. I didn't like
to have my internal member variables in between l and n.

And my big queston is: Where is the difference between an implementation
detail and a private member? Could you spread some light?
And sorry for disturbing the thread.

Ingo
 
V

Victor Bazarov

Ingo said:
Hi Swamp,

this is interesting. I always though its a matter of taste. Is it some
guidelines that tell it?

Swamp probably knows the meaning differently, however, it's usually
advised here in comp.lang.c++ that the leading underscore not be used.
There is a single reason I know: the Standard says that all identifiers
that begin with an underscore and a capital letter are reserved by the
implementation and all identifiers that begin with an underscore are
reserved in the global namespace. Also, any identifiers that have two
consecutive underscores are reserved.

You're totally allowed to use names that begin with underscores inside
a class, provided that the next character is not a capital letter and
not another underscore. However, for the sake of having good habits,
you're better off without names that begin with an underscore.
So I found that my STL is using the "_" prefix ( dinkumware ) everywhere
I looked in.

That's the _implementation_ [of the Standard Library] that is allowed to
use reserved names. You, on the other hand, are not. No compilers make
a fuss out of it, of course. But it's better to follow the rules than
to walk on the line.
I liked that much better than "m_" prefix ( it is not
postfix I think, as it stands BEFORE the actual name ) because I use
autocomplete features and have a nicer ordering that way. I didn't like
to have my internal member variables in between l and n.

That's up to you. Although, if you know that all your member names are
placed between l and n, what's the friggin' difference? As soon as you
type "m_", your get only data members in your auto-completion thing, no?
And my big queston is: Where is the difference between an implementation
detail and a private member? Could you spread some light?

I am sure Swamp will be happy to oblige... And it seems that Swamp wanted
to use "the implementation" instead of "implementation-details". Happens
to the best of us.

V
 
I

Ingo Nolden

Victor said:
Swamp probably knows the meaning differently, however, it's usually
advised here in comp.lang.c++ that the leading underscore not be used.
There is a single reason I know: the Standard says that all identifiers
that begin with an underscore and a capital letter are reserved by the
implementation and all identifiers that begin with an underscore are
reserved in the global namespace. Also, any identifiers that have two
consecutive underscores are reserved.

I knew the last thing. Its for stuff like __int64. The former is new to
me, and sounds quite strict. That way I get again told what to do.
You're totally allowed to use names that begin with underscores inside
a class, provided that the next character is not a capital letter and
not another underscore. However, for the sake of having good habits,
you're better off without names that begin with an underscore.

I see the point of habits. If someone reads others code he should know
as quick as possible what it is about. And if there is such thing as a
common practice then I should use it too ( if I can somehow live with it )
So I found that my STL is using the "_" prefix ( dinkumware )
everywhere I looked in.


That's the _implementation_ [of the Standard Library] that is allowed to
use reserved names. You, on the other hand, are not. No compilers make
a fuss out of it, of course. But it's better to follow the rules than
to walk on the line.

Ok, so where exactly is the border. The standard lib is an
implementation. What about other libs. What about something like boost?
There is not much technical difference between both. Just one is part of
the standard, the other not.
That's up to you. Although, if you know that all your member names are
placed between l and n, what's the friggin' difference? As soon as you
type "m_", your get only data members in your auto-completion thing, no?

True. Its a year ago, or so. I don't know exactly what it was. But it
disturbed me, such that I moved to use _. And it had to do with
autocompletion. I think the actual problem was the other way. When I am
outside the class, and I want to access a member I get the private
members listed between the others. With the underscore I can just scroll
behind them.
I am sure Swamp will be happy to oblige... And it seems that Swamp wanted
to use "the implementation" instead of "implementation-details". Happens
to the best of us.

I am curious.

Anyway. Can you give me a link to the document that says I should use
m_. I want to see what nature it is and I also want to see what other
bad habits I am doing. Or prevent myself from beginning new bad habits.

thanks
Ingo
 
V

Victor Bazarov

Ingo said:
[...]
Anyway. Can you give me a link to the document that says I should use
m_.

No such document exists outside of every employer's coding standards
paper (if any). Microsoft uses 'm_' in their code generators and in
examples, that's why many C++ programmers followed suit, probably.

I do not insist on 'm_' nor do I object to it. Essentially, I am quite
indifferent. Any kind of distinctive marking in fine with me as long as
it is consistent, and does not go against language rules. And I prefer
to have a marking than not to have it.
I want to see what nature it is and I also want to see what other
bad habits I am doing. Or prevent myself from beginning new bad habits.

Read the archives about "coding style" or "coding standards" (use the
quotes to search for the phrase). Alternatively, get a book or two on
coding style; I got none and so I can't recommend any. Herb Sutter
recently published his "C++ Coding Standards", which may include some
naming conventions (look on Amazon or A&W for the ToC of that book),
check it out, I heard good things about it... Anyway, it's the most
recent. I am sure there are other good ones.

V
 
S

Swampmonster

Ingo said:
Hi Swamp,

this is interesting. I always though its a matter of taste. Is it some
guidelines that tell it?

So I found that my STL is using the "_" prefix ( dinkumware ) everywhere
I looked in. I liked that much better than "m_" prefix ( it is not
postfix I think, as it stands BEFORE the actual name ) because I use
autocomplete features and have a nicer ordering that way. I didn't like
to have my internal member variables in between l and n.

And my big queston is: Where is the difference between an implementation
detail and a private member? Could you spread some light?
And sorry for disturbing the thread.

Ingo

Ok, of course I ment "m_" prefix not postfix :) My mistake.
And no, you don't have to use "m_" you can call your member-variables
(or functions or whatever) just "x" if you like, and in some cases it
even makes sense.
I ment if you just want to use some prefix, you could use "m_" because
many people use it. So see it as a proposal, nothing more.
Ah, yes, concerning the missing "const" thing - that's also not
necessary, only in this case when you declare the friend function const,
you shouldn't let it out in the actual definition (or another
declaration), because you then have a different function that is NOT a
friend, which I think was not what you wanted.

bye, swamp'
 
S

Swampmonster

Victor said:
Ingo said:
Hi Swamp,

this is interesting. I always though its a matter of taste. Is it some
guidelines that tell it?


Swamp probably knows the meaning differently, however, it's usually
advised here in comp.lang.c++ that the leading underscore not be used.
There is a single reason I know: the Standard says that all identifiers
that begin with an underscore and a capital letter are reserved by the
implementation and all identifiers that begin with an underscore are
reserved in the global namespace. Also, any identifiers that have two
consecutive underscores are reserved.

You're totally allowed to use names that begin with underscores inside
a class, provided that the next character is not a capital letter and
not another underscore. However, for the sake of having good habits,
you're better off without names that begin with an underscore.
So I found that my STL is using the "_" prefix ( dinkumware )
everywhere I looked in.


That's the _implementation_ [of the Standard Library] that is allowed to
use reserved names. You, on the other hand, are not. No compilers make
a fuss out of it, of course. But it's better to follow the rules than
to walk on the line.
I liked that much better than "m_" prefix ( it is not
postfix I think, as it stands BEFORE the actual name ) because I use
autocomplete features and have a nicer ordering that way. I didn't
like to have my internal member variables in between l and n.


That's up to you. Although, if you know that all your member names are
placed between l and n, what's the friggin' difference? As soon as you
type "m_", your get only data members in your auto-completion thing, no?
And my big queston is: Where is the difference between an
implementation detail and a private member? Could you spread some light?


I am sure Swamp will be happy to oblige... And it seems that Swamp wanted
to use "the implementation" instead of "implementation-details". Happens
to the best of us.

V
100% agreed :)
sorry for the confusion.

bye, swamp'
 
M

msalters

Swampmonster said:
Ingo Nolden wrote:
Ok, of course I ment "m_" prefix not postfix :) My mistake.

Actually, code becomes much more readable when you switch to postfix
annotation. Consider widgetcounter_m versus m_widgetcounter. Which
part is more important, counting widgets or being a member? I'd guess
the first. Anyway, the IDE often will tell you that it's a member,
not that it counts widgets. Therefore you should start with the part
of the name that an IDE can't show you.
Besides, it sorts better.

Regards,
Michiel Salters.
 
I

Ingo Nolden

msalters said:
Actually, code becomes much more readable when you switch to postfix
annotation. Consider widgetcounter_m versus m_widgetcounter. Which
part is more important, counting widgets or being a member? I'd guess
the first. Anyway, the IDE often will tell you that it's a member,
not that it counts widgets. Therefore you should start with the part
of the name that an IDE can't show you.
Besides, it sorts better.


This is exacly what I will never do.
When I access members of a class from outside, then my Ide will show me
everything. The members do have a very little different icon, that I
overlook too easily.
I either want to access a member variable, or a member function or a non
member variable. This is the first I know, then I look which names are
there, and I'll remember which was the one I am looking for. In case of
a simple _ the readablility of the name is equally to the readablility
without anything because the underscore is not something you can read.
The m_ however adds a character to the code that the eye will capture.
The more I think about it, the more I stick to what I begun.

Btw, the way you write widgetcounter makes it also more difficult. What
about _widgetCounter.
 
I

Ingo Nolden

Victor said:
Ingo said:
[...]
Anyway. Can you give me a link to the document that says I should use m_.


No such document exists outside of every employer's coding standards
paper (if any). Microsoft uses 'm_' in their code generators and in
examples, that's why many C++ programmers followed suit, probably.

Microsoft has some good stuff that I like. I copied some of the
architecture from .net in my native c++ code. But everything I copy I
have been thought of for a while if it is really what I want.
I do not insist on 'm_' nor do I object to it. Essentially, I am quite
indifferent. Any kind of distinctive marking in fine with me as long as
it is consistent, and does not go against language rules. And I prefer
to have a marking than not to have it.
I want to see what nature it is and I also want to see what other
bad habits I am doing. Or prevent myself from beginning new bad habits.


Read the archives about "coding style" or "coding standards" (use the
quotes to search for the phrase). Alternatively, get a book or two on
coding style; I got none and so I can't recommend any. Herb Sutter
recently published his "C++ Coding Standards", which may include some
naming conventions (look on Amazon or A&W for the ToC of that book),
check it out, I heard good things about it... Anyway, it's the most
recent. I am sure there are other good ones.


Thank you for these tips. I will watch out for it.

Ingo
 
S

Swampmonster

Btw, the way you write widgetcounter makes it also more difficult. What
about _widgetCounter.

How about m_widget_counter?
I think that's really a question of personal preference. Just dont use
_WidgetCounter - everything else is fine concerning the standard, and
the rest is up to you.
 

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,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top