This question already has answers here:
Meaning of 'const' last in a function declaration of a class?
(12 answers)
Closed 8 years ago.
In the book "Programming Interviews Exposed" by John Mongan (see page 33), theres a function declaration for a Singly Linked List Element:
const T& value() const {...}
I understand what everything before the method name means, namely that it is a reference to a template datatype which you may not modify, but what does the extra const after the value() signify? A constant reference? I thought references were already constant (i.e. unchangeable alias which is the object).
const T& value() const {...}
This means the function value() will return a const T& type and in between (in the function) won't modify the class itself.
Say I write:
class Cfoo
{
void foo() const
{
//Cfoo will not be modified here
}
}
If I directly quote from MS Docs:
Declaring a member function with the const keyword specifies that the function is a "read-only" function that does not modify the object for which it is called. A constant member function cannot modify any non-static data members or call any member functions that aren't constant.
The const after the method name signifies that the method does not modify any field of the object. Therefore, it can be invoked on a const instance of the object.
Related
This question already has answers here:
Meaning of 'const' last in a function declaration of a class?
(12 answers)
Closed 3 years ago.
I got a book, where there is written something like:
class Foo
{
public:
int Bar(int random_arg) const
{
// code
}
};
What does it mean?
A "const function", denoted with the keyword const after a function declaration, makes it a compiler error for this class function to change a member variable of the class. However, reading of a class variables is okay inside of the function, but writing inside of this function will generate a compiler error.
Another way of thinking about such "const function" is by viewing a class function as a normal function taking an implicit this pointer. So a method int Foo::Bar(int random_arg) (without the const at the end) results in a function like int Foo_Bar(Foo* this, int random_arg), and a call such as Foo f; f.Bar(4) will internally correspond to something like Foo f; Foo_Bar(&f, 4). Now adding the const at the end (int Foo::Bar(int random_arg) const) can then be understood as a declaration with a const this pointer: int Foo_Bar(const Foo* this, int random_arg). Since the type of this in such case is const, no modifications of member variables are possible.
It is possible to loosen the "const function" restriction of not allowing the function to write to any variable of a class. To allow some of the variables to be writable even when the function is marked as a "const function", these class variables are marked with the keyword mutable. Thus, if a class variable is marked as mutable, and a "const function" writes to this variable then the code will compile cleanly and the variable is possible to change. (C++11)
As usual when dealing with the const keyword, changing the location of the const key word in a C++ statement has entirely different meanings. The above usage of const only applies when adding const to the end of the function declaration after the parenthesis.
const is a highly overused qualifier in C++: the syntax and ordering is often not straightforward in combination with pointers. Some readings about const correctness and the const keyword:
Const correctness
The C++ 'const' Declaration: Why & How
Consider two class-typed variables:
class Boo { ... };
Boo b0; // mutable object
const Boo b1; // non-mutable object
Now you are able to call any member function of Boo on b0, but only const-qualified member functions on b1.
Bar is guaranteed not to change the object it is being invoked on. See the section about const correctness in the C++ FAQ, for example.
Similar to this question.
In essence it means that the method Bar will not modify non mutable member variables of Foo.
I always find it conceptually easier to think of that you are making the this pointer const (which is pretty much what it does).
Function can't change its parameters via the pointer/reference you gave it.
I go to this page every time I need to think about it:
http://www.parashift.com/c++-faq-lite/const-correctness.html
I believe there's also a good chapter in Meyers' "More Effective C++".
This question already has an answer here:
c++ - const member func, that can be called upon lvalue instances only, using a ref-qualifier
(1 answer)
Closed 2 years ago.
For the following code:
class C
{
public:
void fun() const {};
void fun() const & {};
};
I know that this is illegal, since we cannot overload with const and const &. However, my question is: we already have const member function in the old standard, why did we need to introduce the const & member function? Are there any semantic differences between a const member function and a const-ref member function?
What's the difference between const member function and const-ref member function
Lvalue ref qualified function cannot be called on rvalue instance arguments (unless the function is also const qualified). Unqualified member functions can be.
This question already has answers here:
Why can a const method take a non const reference?
(2 answers)
Closed 2 years ago.
Consider the following code:
#include <iostream>
class ObjectCalculator {
public:
struct Object {
int id = 0;
};
void setObject(Object& object) const {
object.id = 1;
}
Object m_object;
};
int main() {
ObjectCalculator objCalc{};
std::cout << objCalc.m_object.id << std::endl;
objCalc.setObject(objCalc.m_object);
std::cout << objCalc.m_object.id << std::endl;
return 0;
}
I thought this this line should throw an error during compilation since the internal variable is changed via const method setObject:
objCalc.setObject(objCalc.m_object);
but the code compiles with no errors and outputs:
0
1
Could you please clarify why const does not have effect in this case?
const related to the members of the class.
You modifying the method argument, so it can be changed, regardless of const.
const after method applied to the implicit first method argument this, through which all class members accessed.
cppreference
A non-static member function can be declared with a const, volatile,
or const volatile qualifier (this qualifier appears after the
parameter list in the function declaration). Differently cv-qualified
functions have different types and so may overload each other.
In the body of a cv-qualified function, the this pointer is
cv-qualified, e.g. in a const member function, only other const member
functions may be called normally. (A non-const member function may
still be called if const_cast is applied or through an access path
that does not involve this.)
The const qualifier is to tell that the function does not modify this object.
By passing the object to modify as an argument you don't modify this, you modify the object passed as an argument.
If you tried to modify m_object in the function, you would get the error you expected.
This question already has answers here:
Returning non-const reference from a const member function
(3 answers)
Closed 7 years ago.
I have a class with a list as member, and a getter on this list:
class A
{
public:
const std::list<int*>& get() const {
return list;
}
private:
std::list<int*> list;
};
Why the get function has to return a const std::list and not just an std::list ?
Otherwise I get this error :
error: invalid initialization of reference of type 'std::list&'
from expression of type 'const std::list'
The problem is that the function get is declared as const:
const std::list<int*>& get() const
// ^
, so list is considered as a const inside the function.
Hence the attempt to return it as a non-const reference fails.
Problem
The issue here is that get is const qualified, therefore it can only return a const reference to one of its member objects. If you want to return a non-const reference then you have to make get non const-qualified.
If you think about this also makes sense from the point of view of const-correctness: if you are allowed to return a non-const reference to a member object from a const qualified member function, then you can effectively modify a constant object via that reference, for example via:
A const a(...);
std::list<int*> ref = a.get(); // const qualified but returning non const reference
ref.clear(); // wiped out contents of list in `a`
Possible solutions
I'd recommend to provide both overloads as follows:
const std::list<int*>& get() const { return list; }
std::list<int*>& get() { return list; }
At this point it might be worth considering to just make the list public, depending on the context:
struct A {
std::list<int*> list;
};
While writing the following function abs, I get the error:
non-member function unsigned int abs(const T&) cannot have cv-qualifier.
template<typename T>
inline unsigned int abs(const T& t) const
{
return t>0?t:-t;
}
After removing the const qualifier for the function there is no error. Since I am not modifying t inside the function the above code should have compiled. I am wondering why I got the error?
Your desire not to modify t is expressed in const T& t. The ending const specifies that you will not modify any member variable of the class abs belongs to.
Since there is no class where this function belongs to, you get an error.
The const modifier at the end of the function declaration applies to the hidden this parameter for member functions.
As this is a free function, there is no this and that modifier is not needed.
The t parameter already has its own const in the parameter list.
The cv-qualifier on a member function specifies that the this pointer is to have indirected type const (or volatile, const volatile) and that therefore the member function can be called on instances with that qualification.
Free functions (and class static functions) don't have a this pointer.
As we all know, const keyword followed after the argument list indicates that this is a pointer to a pointer constant.
There is a non-member function, it does not belong to the class, so add const opposite end error occurs.
Solution to the problem: is to either become a class member function or remove the const keyword const opposite end