This question already has answers here:
Meaning of 'const' last in a function declaration of a class?
(12 answers)
Closed 5 years ago.
I've seen a lot of uses of the const keyword put after functions in classes, so i wanted to know what was it about. I read up smth at here: http://duramecho.com/ComputerInformation/WhyHowCppConst.html .
It says that const is used because the function "can attempt to alter any member variables in the object" . If this is true, then should it be used everywhere, because i don't want ANY of the member variables to be altered or changed in any way.
class Class2
{ void Method1() const;
int MemberVariable1;}
So, what is the real definition and use of const ?
A const method can be called on a const object:
class CL2
{
public:
void const_method() const;
void method();
private:
int x;
};
const CL2 co;
CL2 o;
co.const_method(); // legal
co.method(); // illegal, can't call regular method on const object
o.const_method(); // legal, can call const method on a regulard object
o.method(); // legal
Furthermore, it also tells the compiler that the const method should not be changing the state of the object and will catch those problems:
void CL2::const_method() const
{
x = 3; // illegal, can't modify a member in a const object
}
There is an exception to the above rule by using the mutable modifier, but you should first get good at const correctness before you venture into that territory.
Others have answered the technical side of your question about const member functions, but there is a bigger picture here -- and that is the idea of const correctness.
Long story short, const correctness is about clarifying and enforcing the semantics of your code. Take a simple example. Look at this function declaration:
bool DoTheThing(char* message);
Suppose someone else wrote this function and you need to call it. Do you know what DoTheThing() does to your char buffer? Maybe it just logs the message to a file, or maybe it changes the string. You can't tell what the semantics of the call are by just looking at the function declaration. If the function doesn't modify the string, then the declaration is const incorrect.
There's practical value to making your functions const correct, too. Namely, depending on the context of the call, you might not be able to call const-incorrect functions without some trickery. For example, assume that you know that DoTheThing() doesn't modify the contents of the string passed to it, and you have this code:
void MyFunction()
{
std::string msg = "Hello, const correctness";
DoTheThing(msg.c_str());
}
The above code won't compile because msg.c_str() returns a const char*. In order to get this code to compile, you would have to do something like this:
void MyFunction()
{
std::string msg = "Hello, const correctness";
DoTheThing(msg.begin());
}
...or even worse:
void MyFunction()
{
std::string msg = "Hello, const correctness";
DoTheThing(const_cast<char*>(msg.c_str()));
}
neither of which, arguably, are 'better' than the original code. But because DoTheThing() was written in a const-incorrect way, you have to bend your code around it.
The meaning is that you guarantee to clients calling a const function member that the state of the object will not change. So when you say a member function is const it means that you do not change any of the objects member variables during the function call.
const, when attached to a non-static class method, tells the compiler that your function doesn't modify the internal state of the object.
This is useful in two ways:
If you do write code that changes internal state in your const method, the compiler catches the error, moving a programming error from run-time to compile-time.
If client code calls a non-const method on a constant pointer, the compiler catches the error, ensuring the "chain of not changing things" is maintained.
Typically you want to declare all non-mutating non-static class methods as const. This allows calling code to use the const qualifier on pointers, and it helps catch mistakes.
Typical C++: you can declare a class member variable "mutable" and then change it even from a const method.
The const keyword used after a method indicate that this method doesn't modify the object on which it's called. This way, this method can be called on a const version of the object.
If this is true, then should it be used everywhere, because i don't want ANY of the member variables to be altered or changed in any way?
Well, no. Sometimes you do want instance methods to modify members. For example, any set method will obviously need to set variables, so it's not the case that you should put const everywhere. But if your object's state is totally immutable, first consider whether it might not be better to have no instances at all (i.e., a static class), and if that's not the case, then make everything const.
It's quite unusual not to want to have any member variables changed, but if that's what your class requires, then you should make all your member functions const.
However, you probably do want to change at least some members:
class A {
private:
int val;
public:
A() : val(0) {}
void Inc() { val++; }
int GetVal() const { return val; };
};
Now if I create two instances of A:
A a1;
const A a2;
I can say:
a1.GetVal();
a2.GetVal();
but I can only say:
a1.Inc();
trying to change the value of a constant object:
a2.Inc();
gives a compilation error.
Related
i'm trying to understand class getters and setters functions...
My question is:
If i design a function that just only get a state from its class (a "getter" function), why mark it as "const member function"?
I mean, why use a const member function if my function is designed to not change any proprieties of its class?
i don't understand please :(
for example:
int GetValue() {return a_private_variable;}
and
int GetValue() const {return a_private_variable;}
what is the real difference?
When you declare a member function as const, like in
int GetValue() const;
then you tell the compiler that it will not modify anything in the object.
That also means you can call the member function on constant object. If you don't have the const modifier then you can't call it on an object that has been defined as const. You can still call const member functions on non-constant objects.
Also note that the const modifier is part of the member function signature, which means you can overload it with a non-const function. That is you can have
int GetValue() const;
int GetValue();
in the same class.
const can show up in three different places in C++.
Example 1:
const Object obj1;
obj1 is a const object. Meaning that you can not change anything on this object. This object can only call const member functions like
int GetValue() const {return a_private_variable;}
Example 2:
int myMethod() const {//do something}
This is a const method. It would be a const member function if it is declared inside of a class. These are the types of methods that const variables can call.
Example 3:
int myMethod(const Object &x) {//do something with x}
This is a method that takes a const parameter. This means that the logic inside myMethod is not allowed to change anything to do with x. Also note the parameter is being passed by reference not by copy. I like to think of this as a read only type of method.
When you are developing software that will be used by others; it is a good idea to not let them break things they don't know they should not break. In this case you can constrain variables, methods, and parameters to be const to guaranteed that the contract is upheld. I tried to summarize the main ideas I learned in college, but there are many resources online around const in C++. Check out this link if you would like to know more. Also it is possible that I remembered somethings incorrectly as I have not been in the C/C++ realm for a while.
A const instance of a class can only call const functions.
Having a const instance of a class is useful for making your programs more stable since then you can't modify the instance by accident.
In your case the functions do exactly the same thing, but it doesn't have to be that way.
i'm trying to understand class getters and setters functions...
My question is:
If i design a function that just only get a state from its class (a "getter" function), why mark it as "const member function"?
I mean, why use a const member function if my function is designed to not change any proprieties of its class?
i don't understand please :(
for example:
int GetValue() {return a_private_variable;}
and
int GetValue() const {return a_private_variable;}
what is the real difference?
When you declare a member function as const, like in
int GetValue() const;
then you tell the compiler that it will not modify anything in the object.
That also means you can call the member function on constant object. If you don't have the const modifier then you can't call it on an object that has been defined as const. You can still call const member functions on non-constant objects.
Also note that the const modifier is part of the member function signature, which means you can overload it with a non-const function. That is you can have
int GetValue() const;
int GetValue();
in the same class.
const can show up in three different places in C++.
Example 1:
const Object obj1;
obj1 is a const object. Meaning that you can not change anything on this object. This object can only call const member functions like
int GetValue() const {return a_private_variable;}
Example 2:
int myMethod() const {//do something}
This is a const method. It would be a const member function if it is declared inside of a class. These are the types of methods that const variables can call.
Example 3:
int myMethod(const Object &x) {//do something with x}
This is a method that takes a const parameter. This means that the logic inside myMethod is not allowed to change anything to do with x. Also note the parameter is being passed by reference not by copy. I like to think of this as a read only type of method.
When you are developing software that will be used by others; it is a good idea to not let them break things they don't know they should not break. In this case you can constrain variables, methods, and parameters to be const to guaranteed that the contract is upheld. I tried to summarize the main ideas I learned in college, but there are many resources online around const in C++. Check out this link if you would like to know more. Also it is possible that I remembered somethings incorrectly as I have not been in the C/C++ realm for a while.
A const instance of a class can only call const functions.
Having a const instance of a class is useful for making your programs more stable since then you can't modify the instance by accident.
In your case the functions do exactly the same thing, but it doesn't have to be that way.
This question already has answers here:
What is the meaning of a const at end of a member function? [duplicate]
(3 answers)
Closed 6 years ago.
There is a class A and it has the following operator() implementation:
void A::operator()(...parameters...) const
{
// operator body
}
What does this const mean?
Methods in C++ can be marked as const like in the above example to indicate that the function does not modify the instance. To enforce this, the this pointer is of type const A* const within the method.
Normally, the this pointer within a method is A* const to indicate that we cannot change what this points to. That is, so that we cannot do this = new A().
But when the type is const A* const we also cannot change any of the properties.
That the method uses this as a const A* and then can only call other const methods.
See this entry of the CPP FAQ.
As already amply described, it means that the method will not modify the observable state of the object. But also, and very importantly, it means the method can be called on a const object, pointer, or reference - a non-const method cannot. ie:
class A
{
public:
void Method1() const
{
}
void Method2()
{
}
};
int main( int /*argc*/, char * /*argv*/ )
{
const A a;
a.Method1(); //ok.
a.Method2(); //compiler error!
return 0;
}
const keyword specifies that the function is a "read-only" function that does not modify the object for which it is called.
It means that calling the operator will not change state of the object.
A const member function promises to not change the observable state of the object.
Under the hood, it might still change state, e.g. of mutable members. However, mutable members should never be visible from anywhere outside the class' interface, i.e. you should never attempt to lie to client code, because client code may validly expect that const functions don't tweak the object's outer hull. Think of mutable as an optimization tool (e.g. for caching and memoization).
Example for mutability:
You have a quadtree class. Under the hood, the quadtree is build up lazily, i.e. on demand; this lazyness is hidden from users of the class. Now, a query-method on that quadtree should be const, because querying a quadtree is expected to not change the quadtree. How do you implement const-correctness and lazyness without breaking C++' rules? Use mutable. Now you have a quadtree that for the user looks const, but you know that under the hood, there's still a lot of change:
class Quadtree {
public:
Quadtree (int depth);
Foo query (Bar which) const;
private:
mutable Node node_;
};
I have an a class which is singleton as defined follows
class myData {
private:
myData (void); // singleton class.
// Copy and assignment is prohibted.
myData (const myData &);
myData & operator=(const myData &);
static myData* s_pInstance;
public:
~myData (void);
static const myData & Instance();
static void Terminate();
void myFunc() { cout << "my function..." ;}
};
// In cpp file.
myData* myData::s_pInstance(NULL);
myData::myData(){}
myData::~myData()
{
s_pInstance = NULL;
}
const myData& myData::Instance()
{
if (s_pInstance == NULL)
{
s_pInstance = new myData();
}
return *(s_pInstance); // want to avoid pointer as user may deallocate it, so i used const referense
}
void main() {
(myData::Instance()).myFunc();
}
I am getting following error
error C2662: 'myData::myFunc' : cannot convert 'this' pointer from 'const myData' to 'myData&'
how to avoid above problem and call a function from Instance function which is returning const reference?
Thanks!
You'd want to declare func() as a constant member function, so the compiler knows it won't violate the const'd return value from the instance() function.
You could instead also make the instance() function return a 'regular' reference as apposed to a const one.
So either turn:
void myFunc() into void myFunc() const
Or turn:
const myData& myData::Instance() into myData& myData::Instance()
If you are calling a function on a const reference, the function you call must also be const, in your case void myFunc() const.
Otherwise you might return a non-const reference, if that works better.
The error says that myData::Instance() is a const instance of the class, and it can't call myFunc() on that, because myFunc() might change the instance, and you can't change a const instance.
Of course, you know that myFunc() can't really change the instance, but you must advertise this fact, as follows:
void myFunc() const { cout << "my function..." ;}
Avoiding the whole discussion of whether Singleton is a good to have pattern or the source of all evil, if you are actually implementing a singleton, chances are that const correctness will not work there as you expect it, so you should be aware of some pitfalls.
First your error: your Instance() static member returns a const reference, and that means that you can only perform operations that do not modify the object, i.e. call member functions marked as const, or use public members if present in a way that do not modify their values. My suggested solution is modify Instance() to return a non-const reference, rather than making func() const as others suggest.
Now for a longer explanation to the problem of const-correctness in general when applied to your particular Singleton problem. The basic problem is that when you implement a type, you divide those members that modify the object from those that don't, and you mark the latter as const member functions so that the compiler knows of your promise (allows you to call that method on a constant object) and helps you not break it (complains if you try to modify the state in the definition of the method). A method that is marked as const can be applied to both a constant and non constant object, but a method that is not marked const can only be applied to an object that is not const.
Back to the original piece of code, if you implement a singleton and the only way of accessing the object is by an Instance() method that returns a const reference, you are basically limiting all user code to use only const methods implemented in your interface. That means that effectively either all methods are non-mutating, or they are useless (const_cast should never be used). That in turn means that if you have any non-const operation you want to provide an Instance() method that returns a non-const reference.
You could consider implementing two variants of Instance(), but that will not be really helpful. Overload resolution will not help in user code to determine which version to use, so you will end up having to different methods: Instance(), ConstInstance() (choose your names), which means that it is up to user code to determine which one to use. The small advantage is that in their code, the choice of accessor will help documenting their intended usage, and maybe even catch some errors, but more often than not they will just call the non-const version because it works.
Given a declaration like this:
class A {
public:
void Foo() const;
};
What does it mean?
Google turns up this:
Member functions should be declared with the const keyword after them if they can operate on a const (this) object. If the function is not declared const, in can not be applied to a const object, and the compiler will give an error message.
But I find that somewhat confusing; can anyone out there put it in better terms?
Thanks.
Consider a variation of your class A.
class A {
public:
void Foo() const;
void Moo();
private:
int m_nState; // Could add mutable keyword if desired
int GetState() const { return m_nState; }
void SetState(int val) { m_nState = val; }
};
const A *A1 = new A();
A *A2 = new A();
A1->Foo(); // OK
A2->Foo(); // OK
A1->Moo(); // Error - Not allowed to call non-const function on const object instance
A2->Moo(); // OK
The const keyword on a function declaration indicates to the compiler that the function is contractually obligated not to modify the state of A. Thus you are unable to call non-const functions within A::Foo nor change the value of member variables.
To illustrate, Foo() may not invoke A::SetState as it is declared non-const, A::GetState however is ok because it is explicitly declared const. The member m_nState may not be changed either unless declared with the keyword mutable.
One example of this usage of const is for 'getter' functions to obtain the value of member variables.
#1800 Information: I forgot about mutable!
The mutable keyword instructs the compiler to accept modifications to the member variable which would otherwise cause a compiler error. It is used when the function needs to modify state but the object is considered logically consistent (constant) regardless of the modification.
This is not an answer, just a side comment. It is highly recommended to declare variables and constants const as much as possible.
This communicates your intent to users of your class (even/especially yourself).
The compiler will keep you honest to those intentions. -- i.e., it's like compiler checked documentation.
By definition, this prevents state changes you weren't expecting and can, possibly, allow you to make reasonable assumptions while in your methods.
const has a funny way of propagating through your code. Thus, it's a really good idea to start using const as early and as often as possible. Deciding to start const-ifying your code late in the game can be painful (easy, but annoying).
If you're using a language with static, compile time checks it's a great idea to make as much use of them as possible... it's just another kind of testing really.
Functions with const qualifier are not allowed to modify any member variables. For example:
class A
{
int x;
mutable int y;
void f() const
{
x = 1; // error
y = 1; // ok because y is mutable
}
};
C++ objects can be declared to be const:
const A obj = new A();
When an object is const, the only member functions that can be called on that object are functions declared to be const. Making an object const can be interpreted as making the object readonly. A const object cannot be changed, i.e. no data members of the object can be changed. Declaring a member function const means that the function is not allowed to make any changes to the data members of the object.
Two suggested best practices from experience:
(1) Declare const functions whenever possible. At first, I found this to be just extra work, but then I started passing my objects to functions with signatures like f(const Object& o), and suddenly the compiler barfed on a line in f such as o.GetAValue(), because I hadn't marked GetAValue as a const function. This can surprise you especially when you subclass something and don't mark your version of the virtual methods as const - in that case the compile could fail on some function you've never heard of before that was written for the base class.
(2) Avoid mutable variables when it's practical. A tempting trap can be to allow read operations to alter state, such as if you're building a "smart" object that does lazy or asynchronous i/o operations. If you can manage this with only one small mutable variable (like a bool), then, in my experience, this makes sense. However, if you find yourself marking every member variable as mutable in order to keep some operations const, you're defeating the purpose of the const keyword. What can go wrong is that a function which thinks it's not altering your class (since it only calls const methods) my invoke a bug in your code, and it could take a lot of effort to even realize this bug is in your class, since the other coder (rightly) assumes your data is const because he or she is only calling const methods.
const has a funny way of propagating through your code. Thus, it's a really good idea to start using const as early and as often as possible. Deciding to start const-ifying your code late in the game can be painful (easy, but annoying).
Additionally, you will easily run into problems if methods that should be const aren't! This will creep through the code as well, and make it worse and worse.
that will cause the method to not be able to alter any member variables of the object