this is a pointer to a window object. the pointer never changes value - points to the same form/window all the time. In this case it looks like you are are returning a refernce to a particular window.
Printable View
this is a pointer to a window object. the pointer never changes value - points to the same form/window all the time. In this case it looks like you are are returning a refernce to a particular window.
what do you mean by "window object"? this is a console program, not a window program. what i want to know is why declare the operator++ function with a const return type? i just dont see what the point is. i'll quote the tutorial im using:
"It is a const reference because the value should not be changed by the function using this Counter."
const Counter& operator++ ()
{
++itsVal;
return *this;
}
why shouldn't the value be changed? it is supposed to change, the idea is to increment it!
It is not saying the value cannot be changed.
It is saying the *this pointer should not be changed.
It is the *this pointer which is returned as reference.
One thing I am not sure is for operator overloading, why must it be always returning *this as ref. Anyone?
I don't see the point either. Remove const modifier, it's your program (isn't it?).Quote:
Originally posted by bruce_smith
what do you mean by "window object"? this is a console program, not a window program. what i want to know is why declare the operator++ function with a const return type? i just dont see what the point is. i'll quote the tutorial im using:
"It is a const reference because the value should not be changed by the function using this Counter."
const Counter& operator++ ()
{
++itsVal;
return *this;
}
why shouldn't the value be changed? it is supposed to change, the idea is to increment it!
Const objects are only returned when you want them to be protected from changes from outside.
And also, it means that it can optimise it out.Quote:
Originally posted by kedaman
I don't see the point either. Remove const modifier, it's your program (isn't it?).
Const objects are only returned when you want them to be protected from changes from outside.
There are two ways of protecting your internal object, one, a const reference. Two, return a new variable. That involves constructing a new variable which takes time. The first way, it knows that you're not changing it, so it can just inline the direct call. So you'd get something like:And any calls would resolve at compile time:Code:class thingie {
public:
const int& val() const { return m_val; }
private:
int m_val;
};
Code:const int &ref = mythingie.val(); // const int &ref = mythingie.m_val
It will inline it if you put inline (or forceinline in msvc, or autoinline) anyway, difference is that the function will be an accessorQuote:
Originally posted by parksie
The first way, it knows that you're not changing it, so it can just inline the direct call.
it returns a const reference because you are not supposed to write
Counter c;
++++c;
If the returned reference is const, this will result in a compiler error as it should be.
Also, you are not supposed to write:
++c = ...;
The result of both pre- and postfix increment/decrement operators are NOT L-values.
Maybe. I read that it is recommended by the standard that such things are not allowed, but it is not necessary. Anyway, I think it makes confusing code, so one shouldn't do it anyway (except you keda :) )
Code isn't confusing, it's the reader that is confused :D In fact you have to code so that it's obvious what you do, not why you do. For that you use comments(, if you're really bored that is)
Pay close attention to that code!!PHP Code:
class Counter
{
public:
Counter(USHORT x) : itsVal(x) { }
~Counter(){}
USHORT GetItsVal()const { return itsVal; }
void SetItsVal(USHORT x) {itsVal = x; }
const Counter& operator++ (); // prefix
const Counter operator++ (int); // postfix
private:
USHORT itsVal;
};
// ...
const Counter& operator++ ()
{
++itsVal;
return *this;
}
// ...
void foo(Counter& c) {
printf("BEFORE:\t\t %d\n", (c++).GetItsVal() );
printf("AFTER: \t\t %d\n", (++c).getItsVal() );
// will increment it then print the value, then increment again
}
// ...
int main(void) {
Counter c(10); // starts at 10
foo(c);
printf("\nFinal: \t\t %d\n", c.getItsVal() );
return 1;
}
What happens is that, when the program starts, a new counter is created with value of 10. You call foo and what it does is:
BEFORE: 10
AFTER: 11
FINAL: 12
That is because the pre-increment opperator (++c) will increment the value to 11 then return a constant reference to itself (*this) after it pre-increments the internal value (10 to 11), but the post-increment (c++) will post-increment the internal value, and return the reference to itself, this will cause it to return first increment next.
This code is valid in C++:
But it will not be very wise to do that because of the obvious.PHP Code:
(((++(((++c)++)++))++).getItsValue())++
I think that the reason it returns a constant reference instead of just a reference is that they do not want that kind of code that i did. They do not want the "incremental chain" where you keep ++'ing!
The constant is really unnecesary!! They are just trying to prevent crazy code such as: ((++(++((++(c++))++)))++).getItsValue() Try it out for yourself, take out the const and do some wild chain like that and see how good it is... that is the good thing about C++ it makes chaning things sooooo easy.
-MoMad ;)
i came to the same conclusion as you moMad, that the only way to utilise the constant reference return is to stop people doing incremental chains. but now another problem, what about just a constant return type for a standard function, not an overload operator?
eg:
const int Test(const int variable)
{
return variable;
}
int main()
{
const int a=5;
int b=Test(a);
}
In this example, does making the return type a const make any difference at all?
bruce
Are you sure about that MoMad? By definition, your code should output this:
BEFORE: 10
AFTER: 12
FINAL: 12
This is because the value is incremented AFTER the first printf (postfix ++), and again BEFORE the second printf(prefix ++) (for a total of +2 before the second output = 12). If your code outputs the thing you wrote, there is some failure in it.
Bruce: No it doesn't because it's only a copy: the return value is copied to b. const doesn't change anything here.
Sorry CornedBee, I made some changes to it because i realized it would not work because of the const so I forgot to change the output also.
It was supposed to be: (without the const)
I made the first one post-increment to avoid the chain error with the constant! I should've cleaned up after myself, but thx for pointing that out.PHP Code:class Counter
{
public:
Counter(USHORT x) : itsVal(x) { }
~Counter(){}
USHORT GetItsVal()const { return itsVal; }
void SetItsVal(USHORT x) {itsVal = x; }
Counter& operator++ (); // prefix
Counter operator++ (int); // postfix
private:
USHORT itsVal;
};
// ...
const Counter& operator++ ()
{
++itsVal;
return *this;
}
// ...
void foo(Counter& c) {
printf("BEFORE:\t\t %d\n", c.GetItsVal() );
printf("AFTER: \t\t %d\n", ((++c)++).getItsVal() );
// will increment it then print the value, then increment again
}
// ...
int main(void) {
Counter c(10); // starts at 10
foo(c);
printf("\nFinal: \t\t %d\n", c.getItsVal() );
return 1;
}
Hey Bruce,
The const in your code just makes sure that you dont try to mess around with this variable you returned. But the thing is, it is absolutely unnecesary because that value being returned is a "copy" of the original and will not have any effect on the original wether you change it or not. A const reference is the same thing as a copy except a reference is 4bytes and a copy is n bytes where n is the size of the original!!
So it always helps to use const reference or pointer instead of a full copy!!
Regards,PHP Code:const int Test(const int variable)
{
// The parameter AND the return type are already copies of the
// original so it doesnt make sense to make them const
return variable;
}
int main()
{
const int a=5;
int b=Test(a); // This has no effect on b. Is like saying b = 5
// infact you can try incrementing b here, it is valid!!
}
MoMad
Hmm, i had a look myself too and it seems like it´s useless to increment the copy, if you want to have the copy incremented by one, a +1 would do, as ++ is meant to be for variables with scope, not parts of an expression, but assigning is just meaningless.
All the cases i've been assigning incremented postfix expressions are pointers, and incremented pointers were dereferenced before the assignment (and it looks like *x++=...) thats why i thought it was legal.
Hehehe, hmmm I see we still have C-purists :D <internal-joke> Yea I LOVE playing with pointers, its what makes C/C++ so different from ANY OTHER LANGUAGE!!
You can make your own strcpy function, like:
See, As simple as said :DPHP Code:char* strcpy( char* dest, const char* src ) {
while( *src )
*dest++ = *src++;
*dest = 0;
return dest;
}
no we don't :D At least i'm C++ purist, so doing pointer aritmetics doesnt bring me satisfaction. That however doesn't mean I don't so all the time, since it's the best way to save performance, and somehow it's become the standard way of iterating trough containers
Also, it beats #including a whole library <string.h> just to use one simple function (strcpy). Instead, its better to inline it and/or make it a fastcall function :) BTW: C-Purist is also the same as C++-purist, it just doesnt make sense to have pluses and minuses in the same word ;) (at least thats what i meant)
-MoMad
Well, since it's only definitions and constants all you lose is compile time...so there's no eventual benefit to doing that.Quote:
Originally posted by MoMad
Also, it beats #including a whole library <string.h> just to use one simple function (strcpy). Instead, its better to inline it and/or make it a fastcall function :) BTW: C-Purist is also the same as C++-purist, it just doesnt make sense to have pluses and minuses in the same word ;) (at least thats what i meant)
-MoMad
Parksie, it will include the whole library into your project and compile it into your exe making it much larger and possibly slower. So yes, there are benefits :)
But...but...but...it's all in a single .o file...Quote:
Originally posted by MoMad
Parksie, it will include the whole library into your project and compile it into your exe making it much larger and possibly slower. So yes, there are benefits :)
The way the MS linker seems to work is that it can link to a minimum granularity of a single output file. Since most of the functions in the MS implementation of the CRT are all in their own files, it won't make much difference.
PS: If anything, it'll be larger, but definitely not slower unless you inline it.
PPS: With a string object, it'll most likely be inlined anyway :)
strcpy in VC++ is an intrinsic function, which is the VC equivalent for C++ inlining.
I wonder how many of the extensions in VC++ are just there to make the CRT writers' lives easier :p
Beware of some of the intrinsic functions though - a few are a bit buggy (c.f. Knowledge Base).