Sign in to follow this  

[C++] a few questions regarding consts an '&'

This topic is 2667 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello everyone,

I am really confused about a couple of stuff, first off, why do we give one of our class methods the const keyword? (e.g. void GetNum ( void ) const; ) as far as i've read, it makes it "read only", meaning that the function doesn't want to, and wont change any variable, but well, since we wrote the method, why tell the compiler that it wont change anything when we wont actually write code that will change something? could someone show me the point of using const methods?

my second question is, what is the difference between this:

void ChangeNumberToSeven ( int* num )
{
*num = 7;
}





and this:

void ChangeNumberToSeven ( int& num )
{
num = 7;
}





Thanks for your time
-Hassan

Share this post


Link to post
Share on other sites
Quote:
Original post by Hassanbasil
I am really confused about a couple of stuff, first off, why do we give one of our class methods the const keyword? (e.g. void GetNum ( void ) const; ) as far as i've read, it makes it "read only", meaning that the function doesn't want to, and wont change any variable, but well, since we wrote the method, why tell the compiler that it wont change anything when we wont actually write code that will change something? could someone show me the point of using const methods?

Because the compiler may not always be able to determine which methods are const and which ones aren't. For instance, let' say you have two classes Foo and Bar in their own translation units, and you try to do something like this:
void Bar::doIt(const Foo* foo) {
foo->doSomethingElse();
}
Whether or not this code compiles depends on whether or not doSomethingElse is const. However this information can't be inferred by the compilers since the implementation is in another TU, so we have to tell the compiler explicitly in the declaration.

Quote:
my second question is, what is the difference between this:
*** Source Snippet Removed ***

and this:
*** Source Snippet Removed ***

Pointers can be NULL whereas references can't, so from an interface standpoint pointers say "this parameter isn't always required but sometimes you might want/need it" while references say "this parameter is always required". Also, pointers and references are more efficient when you're passing large types around. Plus, references act as aliases, so the compiler can generate better code when it knows you don't really need pointer semantics.

Share this post


Link to post
Share on other sites
1) applying const liberally is a good idea. Marking things read-only is both for your use and the use of others. Suppose you have these classes

class foo // a bad class!
{
public:
foo() : x(5) {}
int &getX() { return x; }
private:
int x;
};

class bar // a good, const correct class!
{
public:
bar() : x(5) {}
const int &getX() const { return x; }
private:
int x;
};

int main()
{
foo f; bar b;

foo.getX() = 2; // this compiles just fine
std::cout << foo.getX() << std::endl; // outputs 2

bar.getX() = 2; // this does not compile
std::cout << bar.getX() << std::endl; // can only output 5, since there is no way to edit foo::x
}




See, you might, for the moment, remember that "foo::getX()" is an accessor, and to never write to it. But others don't know that, and two months from now you might not remember it either. By using the const, you insure the compile won't let you write something that modifies the value without you knowing about it. But, as soon as you start using const, you need to be fully const correct in your program to insure everything works right. Like many language features, the const modifier is there to keep you from making mistakes. Use it, and love it.


2) The difference is in the fact that a reference can't be rebound, and must be valid. You can make a pointer point at something else, and it can even point to entierly invalid things. Pointers can also be manually initialized to "NULL" or "0" value that represents that it isn't pointing at anything. Consider the following:

class thing
{
public:
thing() {}
const int max() const { return 2; }
private:
};

bool ClampHighValue( int &value, const thing &t, int *remainder = NULL )
{
if( value > t.max() )
{
if( remainder )
*remainder = value - t.max();
value = t.max();
return true;
}
return false;
}

int x = 4; thing t; int remainder;
ClampHighValue( x, t );
x = 4;
ClampHighValue( x, t, &remainder );




Notice several things:
*value is a reference, we know it is valid.
*t is a const reference, we know it is valid, and we can't accidently modify it.
*remainder defaults to NULL, but you could pass in some other pointer. thus, remainder is "optional".
*remainder, because it can be null, must be validated before we attempt to write to it.
*thing has consts on the "max" member because otherwise it wouldn't compile when we call t.max(), as t is also const.

[Edited by - KulSeran on August 28, 2010 4:48:13 AM]

Share this post


Link to post
Share on other sites
Also if you have a const instance of a class, you can only call methods that are const on it.


class A
{
void foo(); // why bother with const, I know what I'm doing, right?
void bar() const;
};

void f(const A a)
{
a.foo(); // error, calling non-const method on const object
a.bar(); // no problem
}

Share this post


Link to post
Share on other sites
Actually you're not only telling the compiler that a method is const, but you're telling it to *yourself* (and other developers). The compiler then helps you enforcing it.

You can live without const but it's here to help.

Share this post


Link to post
Share on other sites
Quote:
Original post by SriLumpa
Actually you're not only telling the compiler that a method is const, but you're telling it to *yourself* (and other developers). The compiler then helps you enforcing it.

You can live without const but it's here to help.


So the compiler is not using the information to do any kind of optimization?

Share this post


Link to post
Share on other sites
Quote:
Original post by Tom KQT
Quote:
Original post by SriLumpa
Actually you're not only telling the compiler that a method is const, but you're telling it to *yourself* (and other developers). The compiler then helps you enforcing it.

You can live without const but it's here to help.


So the compiler is not using the information to do any kind of optimization?

For any instance where having const would allow the compiler to optimize the code, the compiler will likely preform the same optimization anyway.

Anything you type in the code that involves hard-coded inputs like "int a = 5", the compiler knows is constant from the "5" until you modify A. The compiler will do constant folding step on it, and propagate that 5 directly to every place it can before actually creating a variable "a" on the stack. If this completely removes the variable, then it doesn't matter if you said it was const or not.

Beyond that, there are a tonne of optimizations that will take place. Small functions get inlined. Dataflow and other steps will move code around ( like moving constant stuff outside of a loop ). And register analysis will allocate registers to all your variables. The compiler can usually determine when things are locally being used as constants, and move them around for the best effect. Telling it that it is always const doesn't change the optimization route taken because at the optimizer level, it can already tell if you modified the values or not.

There might be edge cases, but in general you are putting the const there to help yourself more than the compiler.

Share this post


Link to post
Share on other sites
Quote:
Original post by SriLumpa
You can live without const but it's here to help.
Well mostly, but you'd likely have to live without some of the SC++L as well.

For example, try putting a bunch of items into a std::set and iterating over them, calling a getter for each one.

Share this post


Link to post
Share on other sites
P.S. The compiler can optimize some small set of things better if const is set correctly. Not inside of the function itself, but in calling code. As they may be compiled separately, certain operations cannot be performed when calling a non-const function.

Share this post


Link to post
Share on other sites

This topic is 2667 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this