const parameter and const method in c++ - c++

I have a class like this:
class MyClass
{
const int GetValue()
{
return 2;
}
}
and I am passing it to a function like this:
void Test(const MyClass &myClass)
{
int x=myClass.GetValue();
}
But I am getting this error:
The object has type qualifiers that are not compatible with member function Object type is const MyClass
I know that if I define function like this:
void Test( MyClass &myClass)
But I want to know why adding const should generate such error?

You need to make the member function const, not the return type:
int GetValue() const;
This makes it possible to call this member on a const instance (or via a const reference or pointer).
Note: as you are returning by value, the constness of the thing you return is decoupled from the constness of the object returning it. In fact, it is very unlikely that you want the return type to be const.

You set the int to const, try making the method const like so:
const int GetValue() const
{
return 2;
}

There are two problems, a visibility problem (your const int GetValue() function is not visible since private) and the fact that you're calling a non-const function (which can perform modifications to the object which has it as a member function)
const int GetValue()
from a constant reference to the class
const MyClass &myClass
you are basically asking for "This object shall not be modified, anyway let me call a function which does not guarantee this".
You're not being coherent.

Related

What does method declaration ending in const mean in C++? [duplicate]

What is the meaning of const in declarations like these? The const confuses me.
class foobar
{
public:
operator int () const;
const char* foo() const;
};
When you add the const keyword to a method the this pointer will essentially become a pointer to const object, and you cannot therefore change any member data. (Unless you use mutable, more on that later).
The const keyword is part of the functions signature which means that you can implement two similar methods, one which is called when the object is const, and one that isn't.
#include <iostream>
class MyClass
{
private:
int counter;
public:
void Foo()
{
std::cout << "Foo" << std::endl;
}
void Foo() const
{
std::cout << "Foo const" << std::endl;
}
};
int main()
{
MyClass cc;
const MyClass& ccc = cc;
cc.Foo();
ccc.Foo();
}
This will output
Foo
Foo const
In the non-const method you can change the instance members, which you cannot do in the const version. If you change the method declaration in the above example to the code below you will get some errors.
void Foo()
{
counter++; //this works
std::cout << "Foo" << std::endl;
}
void Foo() const
{
counter++; //this will not compile
std::cout << "Foo const" << std::endl;
}
This is not completely true, because you can mark a member as mutable and a const method can then change it. It's mostly used for internal counters and stuff. The solution for that would be the below code.
#include <iostream>
class MyClass
{
private:
mutable int counter;
public:
MyClass() : counter(0) {}
void Foo()
{
counter++;
std::cout << "Foo" << std::endl;
}
void Foo() const
{
counter++; // This works because counter is `mutable`
std::cout << "Foo const" << std::endl;
}
int GetInvocations() const
{
return counter;
}
};
int main(void)
{
MyClass cc;
const MyClass& ccc = cc;
cc.Foo();
ccc.Foo();
std::cout << "Foo has been invoked " << ccc.GetInvocations() << " times" << std::endl;
}
which would output
Foo
Foo const
Foo has been invoked 2 times
The const means that the method promises not to alter any members of the class. You'd be able to execute the object's members that are so marked, even if the object itself were marked const:
const foobar fb;
fb.foo();
would be legal.
See How many and which are the uses of “const” in C++? for more information.
The const qualifier means that the methods can be called on any value of foobar. The difference comes when you consider calling a non-const method on a const object. Consider if your foobar type had the following extra method declaration:
class foobar {
...
const char* bar();
}
The method bar() is non-const and can only be accessed from non-const values.
void func1(const foobar& fb1, foobar& fb2) {
const char* v1 = fb1.bar(); // won't compile
const char* v2 = fb2.bar(); // works
}
The idea behind const though is to mark methods which will not alter the internal state of the class. This is a powerful concept but is not actually enforceable in C++. It's more of a promise than a guarantee. And one that is often broken and easily broken.
foobar& fbNonConst = const_cast<foobar&>(fb1);
These const mean that compiler will Error if the method 'with const' changes internal data.
class A
{
public:
A():member_()
{
}
int hashGetter() const
{
state_ = 1;
return member_;
}
int goodGetter() const
{
return member_;
}
int getter() const
{
//member_ = 2; // error
return member_;
}
int badGetter()
{
return member_;
}
private:
mutable int state_;
int member_;
};
The test
int main()
{
const A a1;
a1.badGetter(); // doesn't work
a1.goodGetter(); // works
a1.hashGetter(); // works
A a2;
a2.badGetter(); // works
a2.goodGetter(); // works
a2.hashGetter(); // works
}
Read this for more information
Blair's answer is on the mark.
However note that there is a mutable qualifier which may be added to a class's data members. Any member so marked can be modified in a const method without violating the const contract.
You might want to use this (for example) if you want an object to remember how many times a particular method is called, whilst not affecting the "logical" constness of that method.
Meaning of a Const Member Function in C++ Common Knowledge: Essential Intermediate Programming gives a clear explanation:
The type of the this pointer in a non-const member function of a class
X is X * const. That is, it’s a constant pointer to a non-constant X
(see Const Pointers and Pointers to Const [7, 21]). Because the object
to which this refers is not const, it can be modified. The type of
this in a const member function of a class X is const X * const. That
is, it’s a constant pointer to a constant X. Because the object to
which this refers is const, it cannot be modified. That’s the
difference between const and non-const member functions.
So in your code:
class foobar
{
public:
operator int () const;
const char* foo() const;
};
You can think it as this:
class foobar
{
public:
operator int (const foobar * const this) const;
const char* foo(const foobar * const this) const;
};
I would like to add the following point.
You can also make it a const & and const &&
So,
struct s{
void val1() const {
// *this is const here. Hence this function cannot modify any member of *this
}
void val2() const & {
// *this is const& here
}
void val3() const && {
// The object calling this function should be const rvalue only.
}
void val4() && {
// The object calling this function should be rvalue reference only.
}
};
int main(){
s a;
a.val1(); //okay
a.val2(); //okay
// a.val3() not okay, a is not rvalue will be okay if called like
std::move(a).val3(); // okay, move makes it a rvalue
}
Feel free to improve the answer. I am no expert
when you use const in the method signature (like your said: const char* foo() const;) you are telling the compiler that memory pointed to by this can't be changed by this method (which is foo here).
Here const means that at that function any variable's value can not change
class Test{
private:
int a;
public:
void test()const{
a = 10;
}
};
And like this example, if you try to change the value of a variable in the test function you will get an error.
The const keyword used with the function declaration specifies that it is a const member function and it will not be able to change the data members of the object.
https://isocpp.org/wiki/faq/const-correctness#const-member-fns
What is a "const member function"?
A member function that inspects (rather than mutates) its object.
A const member function is indicated by a const suffix just after the member function’s parameter list. Member functions with a const suffix are called “const member functions” or “inspectors.” Member functions without a const suffix are called “non-const member functions” or “mutators.”
class Fred {
public:
void inspect() const; // This member promises NOT to change *this
void mutate(); // This member function might change *this
};
void userCode(Fred& changeable, const Fred& unchangeable)
{
changeable.inspect(); // Okay: doesn't change a changeable object
changeable.mutate(); // Okay: changes a changeable object
unchangeable.inspect(); // Okay: doesn't change an unchangeable object
unchangeable.mutate(); // ERROR: attempt to change unchangeable object
}
The attempt to call unchangeable.mutate() is an error caught at compile time. There is no runtime space or speed penalty for const, and you don’t need to write test-cases to check it at runtime.
The trailing const on inspect() member function should be used to mean the method won’t change the object’s abstract (client-visible) state. That is slightly different from saying the method won’t change the “raw bits” of the object’s struct. C++ compilers aren’t allowed to take the “bitwise” interpretation unless they can solve the aliasing problem, which normally can’t be solved (i.e., a non-const alias could exist which could modify the state of the object). Another (important) insight from this aliasing issue: pointing at an object with a pointer-to-const doesn’t guarantee that the object won’t change; it merely promises that the object won’t change via that pointer.
In const objects only const methods can be called. All fielnd in such a method considered as const field.
Last issue has curious effect:
pointer becomes a const pointer int* const, which is not the same as a pointer to const const int*. Thus you can alter the object which pointer points to, but can't make pointer to point to another object.
reference should become a const reference, but it is invariantly a const reference: you can not re-init it to another object. But again you can alter the object which reference refers to.

Why is const in component function in class necessary [duplicate]

What is the meaning of const in declarations like these? The const confuses me.
class foobar
{
public:
operator int () const;
const char* foo() const;
};
When you add the const keyword to a method the this pointer will essentially become a pointer to const object, and you cannot therefore change any member data. (Unless you use mutable, more on that later).
The const keyword is part of the functions signature which means that you can implement two similar methods, one which is called when the object is const, and one that isn't.
#include <iostream>
class MyClass
{
private:
int counter;
public:
void Foo()
{
std::cout << "Foo" << std::endl;
}
void Foo() const
{
std::cout << "Foo const" << std::endl;
}
};
int main()
{
MyClass cc;
const MyClass& ccc = cc;
cc.Foo();
ccc.Foo();
}
This will output
Foo
Foo const
In the non-const method you can change the instance members, which you cannot do in the const version. If you change the method declaration in the above example to the code below you will get some errors.
void Foo()
{
counter++; //this works
std::cout << "Foo" << std::endl;
}
void Foo() const
{
counter++; //this will not compile
std::cout << "Foo const" << std::endl;
}
This is not completely true, because you can mark a member as mutable and a const method can then change it. It's mostly used for internal counters and stuff. The solution for that would be the below code.
#include <iostream>
class MyClass
{
private:
mutable int counter;
public:
MyClass() : counter(0) {}
void Foo()
{
counter++;
std::cout << "Foo" << std::endl;
}
void Foo() const
{
counter++; // This works because counter is `mutable`
std::cout << "Foo const" << std::endl;
}
int GetInvocations() const
{
return counter;
}
};
int main(void)
{
MyClass cc;
const MyClass& ccc = cc;
cc.Foo();
ccc.Foo();
std::cout << "Foo has been invoked " << ccc.GetInvocations() << " times" << std::endl;
}
which would output
Foo
Foo const
Foo has been invoked 2 times
The const means that the method promises not to alter any members of the class. You'd be able to execute the object's members that are so marked, even if the object itself were marked const:
const foobar fb;
fb.foo();
would be legal.
See How many and which are the uses of “const” in C++? for more information.
The const qualifier means that the methods can be called on any value of foobar. The difference comes when you consider calling a non-const method on a const object. Consider if your foobar type had the following extra method declaration:
class foobar {
...
const char* bar();
}
The method bar() is non-const and can only be accessed from non-const values.
void func1(const foobar& fb1, foobar& fb2) {
const char* v1 = fb1.bar(); // won't compile
const char* v2 = fb2.bar(); // works
}
The idea behind const though is to mark methods which will not alter the internal state of the class. This is a powerful concept but is not actually enforceable in C++. It's more of a promise than a guarantee. And one that is often broken and easily broken.
foobar& fbNonConst = const_cast<foobar&>(fb1);
These const mean that compiler will Error if the method 'with const' changes internal data.
class A
{
public:
A():member_()
{
}
int hashGetter() const
{
state_ = 1;
return member_;
}
int goodGetter() const
{
return member_;
}
int getter() const
{
//member_ = 2; // error
return member_;
}
int badGetter()
{
return member_;
}
private:
mutable int state_;
int member_;
};
The test
int main()
{
const A a1;
a1.badGetter(); // doesn't work
a1.goodGetter(); // works
a1.hashGetter(); // works
A a2;
a2.badGetter(); // works
a2.goodGetter(); // works
a2.hashGetter(); // works
}
Read this for more information
Blair's answer is on the mark.
However note that there is a mutable qualifier which may be added to a class's data members. Any member so marked can be modified in a const method without violating the const contract.
You might want to use this (for example) if you want an object to remember how many times a particular method is called, whilst not affecting the "logical" constness of that method.
Meaning of a Const Member Function in C++ Common Knowledge: Essential Intermediate Programming gives a clear explanation:
The type of the this pointer in a non-const member function of a class
X is X * const. That is, it’s a constant pointer to a non-constant X
(see Const Pointers and Pointers to Const [7, 21]). Because the object
to which this refers is not const, it can be modified. The type of
this in a const member function of a class X is const X * const. That
is, it’s a constant pointer to a constant X. Because the object to
which this refers is const, it cannot be modified. That’s the
difference between const and non-const member functions.
So in your code:
class foobar
{
public:
operator int () const;
const char* foo() const;
};
You can think it as this:
class foobar
{
public:
operator int (const foobar * const this) const;
const char* foo(const foobar * const this) const;
};
I would like to add the following point.
You can also make it a const & and const &&
So,
struct s{
void val1() const {
// *this is const here. Hence this function cannot modify any member of *this
}
void val2() const & {
// *this is const& here
}
void val3() const && {
// The object calling this function should be const rvalue only.
}
void val4() && {
// The object calling this function should be rvalue reference only.
}
};
int main(){
s a;
a.val1(); //okay
a.val2(); //okay
// a.val3() not okay, a is not rvalue will be okay if called like
std::move(a).val3(); // okay, move makes it a rvalue
}
Feel free to improve the answer. I am no expert
when you use const in the method signature (like your said: const char* foo() const;) you are telling the compiler that memory pointed to by this can't be changed by this method (which is foo here).
Here const means that at that function any variable's value can not change
class Test{
private:
int a;
public:
void test()const{
a = 10;
}
};
And like this example, if you try to change the value of a variable in the test function you will get an error.
The const keyword used with the function declaration specifies that it is a const member function and it will not be able to change the data members of the object.
https://isocpp.org/wiki/faq/const-correctness#const-member-fns
What is a "const member function"?
A member function that inspects (rather than mutates) its object.
A const member function is indicated by a const suffix just after the member function’s parameter list. Member functions with a const suffix are called “const member functions” or “inspectors.” Member functions without a const suffix are called “non-const member functions” or “mutators.”
class Fred {
public:
void inspect() const; // This member promises NOT to change *this
void mutate(); // This member function might change *this
};
void userCode(Fred& changeable, const Fred& unchangeable)
{
changeable.inspect(); // Okay: doesn't change a changeable object
changeable.mutate(); // Okay: changes a changeable object
unchangeable.inspect(); // Okay: doesn't change an unchangeable object
unchangeable.mutate(); // ERROR: attempt to change unchangeable object
}
The attempt to call unchangeable.mutate() is an error caught at compile time. There is no runtime space or speed penalty for const, and you don’t need to write test-cases to check it at runtime.
The trailing const on inspect() member function should be used to mean the method won’t change the object’s abstract (client-visible) state. That is slightly different from saying the method won’t change the “raw bits” of the object’s struct. C++ compilers aren’t allowed to take the “bitwise” interpretation unless they can solve the aliasing problem, which normally can’t be solved (i.e., a non-const alias could exist which could modify the state of the object). Another (important) insight from this aliasing issue: pointing at an object with a pointer-to-const doesn’t guarantee that the object won’t change; it merely promises that the object won’t change via that pointer.
In const objects only const methods can be called. All fielnd in such a method considered as const field.
Last issue has curious effect:
pointer becomes a const pointer int* const, which is not the same as a pointer to const const int*. Thus you can alter the object which pointer points to, but can't make pointer to point to another object.
reference should become a const reference, but it is invariantly a const reference: you can not re-init it to another object. But again you can alter the object which reference refers to.

Why do I have to const-qualify my function? [duplicate]

What is the meaning of const in declarations like these? The const confuses me.
class foobar
{
public:
operator int () const;
const char* foo() const;
};
When you add the const keyword to a method the this pointer will essentially become a pointer to const object, and you cannot therefore change any member data. (Unless you use mutable, more on that later).
The const keyword is part of the functions signature which means that you can implement two similar methods, one which is called when the object is const, and one that isn't.
#include <iostream>
class MyClass
{
private:
int counter;
public:
void Foo()
{
std::cout << "Foo" << std::endl;
}
void Foo() const
{
std::cout << "Foo const" << std::endl;
}
};
int main()
{
MyClass cc;
const MyClass& ccc = cc;
cc.Foo();
ccc.Foo();
}
This will output
Foo
Foo const
In the non-const method you can change the instance members, which you cannot do in the const version. If you change the method declaration in the above example to the code below you will get some errors.
void Foo()
{
counter++; //this works
std::cout << "Foo" << std::endl;
}
void Foo() const
{
counter++; //this will not compile
std::cout << "Foo const" << std::endl;
}
This is not completely true, because you can mark a member as mutable and a const method can then change it. It's mostly used for internal counters and stuff. The solution for that would be the below code.
#include <iostream>
class MyClass
{
private:
mutable int counter;
public:
MyClass() : counter(0) {}
void Foo()
{
counter++;
std::cout << "Foo" << std::endl;
}
void Foo() const
{
counter++; // This works because counter is `mutable`
std::cout << "Foo const" << std::endl;
}
int GetInvocations() const
{
return counter;
}
};
int main(void)
{
MyClass cc;
const MyClass& ccc = cc;
cc.Foo();
ccc.Foo();
std::cout << "Foo has been invoked " << ccc.GetInvocations() << " times" << std::endl;
}
which would output
Foo
Foo const
Foo has been invoked 2 times
The const means that the method promises not to alter any members of the class. You'd be able to execute the object's members that are so marked, even if the object itself were marked const:
const foobar fb;
fb.foo();
would be legal.
See How many and which are the uses of “const” in C++? for more information.
The const qualifier means that the methods can be called on any value of foobar. The difference comes when you consider calling a non-const method on a const object. Consider if your foobar type had the following extra method declaration:
class foobar {
...
const char* bar();
}
The method bar() is non-const and can only be accessed from non-const values.
void func1(const foobar& fb1, foobar& fb2) {
const char* v1 = fb1.bar(); // won't compile
const char* v2 = fb2.bar(); // works
}
The idea behind const though is to mark methods which will not alter the internal state of the class. This is a powerful concept but is not actually enforceable in C++. It's more of a promise than a guarantee. And one that is often broken and easily broken.
foobar& fbNonConst = const_cast<foobar&>(fb1);
These const mean that compiler will Error if the method 'with const' changes internal data.
class A
{
public:
A():member_()
{
}
int hashGetter() const
{
state_ = 1;
return member_;
}
int goodGetter() const
{
return member_;
}
int getter() const
{
//member_ = 2; // error
return member_;
}
int badGetter()
{
return member_;
}
private:
mutable int state_;
int member_;
};
The test
int main()
{
const A a1;
a1.badGetter(); // doesn't work
a1.goodGetter(); // works
a1.hashGetter(); // works
A a2;
a2.badGetter(); // works
a2.goodGetter(); // works
a2.hashGetter(); // works
}
Read this for more information
Blair's answer is on the mark.
However note that there is a mutable qualifier which may be added to a class's data members. Any member so marked can be modified in a const method without violating the const contract.
You might want to use this (for example) if you want an object to remember how many times a particular method is called, whilst not affecting the "logical" constness of that method.
Meaning of a Const Member Function in C++ Common Knowledge: Essential Intermediate Programming gives a clear explanation:
The type of the this pointer in a non-const member function of a class
X is X * const. That is, it’s a constant pointer to a non-constant X
(see Const Pointers and Pointers to Const [7, 21]). Because the object
to which this refers is not const, it can be modified. The type of
this in a const member function of a class X is const X * const. That
is, it’s a constant pointer to a constant X. Because the object to
which this refers is const, it cannot be modified. That’s the
difference between const and non-const member functions.
So in your code:
class foobar
{
public:
operator int () const;
const char* foo() const;
};
You can think it as this:
class foobar
{
public:
operator int (const foobar * const this) const;
const char* foo(const foobar * const this) const;
};
I would like to add the following point.
You can also make it a const & and const &&
So,
struct s{
void val1() const {
// *this is const here. Hence this function cannot modify any member of *this
}
void val2() const & {
// *this is const& here
}
void val3() const && {
// The object calling this function should be const rvalue only.
}
void val4() && {
// The object calling this function should be rvalue reference only.
}
};
int main(){
s a;
a.val1(); //okay
a.val2(); //okay
// a.val3() not okay, a is not rvalue will be okay if called like
std::move(a).val3(); // okay, move makes it a rvalue
}
Feel free to improve the answer. I am no expert
when you use const in the method signature (like your said: const char* foo() const;) you are telling the compiler that memory pointed to by this can't be changed by this method (which is foo here).
Here const means that at that function any variable's value can not change
class Test{
private:
int a;
public:
void test()const{
a = 10;
}
};
And like this example, if you try to change the value of a variable in the test function you will get an error.
The const keyword used with the function declaration specifies that it is a const member function and it will not be able to change the data members of the object.
https://isocpp.org/wiki/faq/const-correctness#const-member-fns
What is a "const member function"?
A member function that inspects (rather than mutates) its object.
A const member function is indicated by a const suffix just after the member function’s parameter list. Member functions with a const suffix are called “const member functions” or “inspectors.” Member functions without a const suffix are called “non-const member functions” or “mutators.”
class Fred {
public:
void inspect() const; // This member promises NOT to change *this
void mutate(); // This member function might change *this
};
void userCode(Fred& changeable, const Fred& unchangeable)
{
changeable.inspect(); // Okay: doesn't change a changeable object
changeable.mutate(); // Okay: changes a changeable object
unchangeable.inspect(); // Okay: doesn't change an unchangeable object
unchangeable.mutate(); // ERROR: attempt to change unchangeable object
}
The attempt to call unchangeable.mutate() is an error caught at compile time. There is no runtime space or speed penalty for const, and you don’t need to write test-cases to check it at runtime.
The trailing const on inspect() member function should be used to mean the method won’t change the object’s abstract (client-visible) state. That is slightly different from saying the method won’t change the “raw bits” of the object’s struct. C++ compilers aren’t allowed to take the “bitwise” interpretation unless they can solve the aliasing problem, which normally can’t be solved (i.e., a non-const alias could exist which could modify the state of the object). Another (important) insight from this aliasing issue: pointing at an object with a pointer-to-const doesn’t guarantee that the object won’t change; it merely promises that the object won’t change via that pointer.
In const objects only const methods can be called. All fielnd in such a method considered as const field.
Last issue has curious effect:
pointer becomes a const pointer int* const, which is not the same as a pointer to const const int*. Thus you can alter the object which pointer points to, but can't make pointer to point to another object.
reference should become a const reference, but it is invariantly a const reference: you can not re-init it to another object. But again you can alter the object which reference refers to.

Where can I learn more about const? [duplicate]

What is the meaning of const in declarations like these? The const confuses me.
class foobar
{
public:
operator int () const;
const char* foo() const;
};
When you add the const keyword to a method the this pointer will essentially become a pointer to const object, and you cannot therefore change any member data. (Unless you use mutable, more on that later).
The const keyword is part of the functions signature which means that you can implement two similar methods, one which is called when the object is const, and one that isn't.
#include <iostream>
class MyClass
{
private:
int counter;
public:
void Foo()
{
std::cout << "Foo" << std::endl;
}
void Foo() const
{
std::cout << "Foo const" << std::endl;
}
};
int main()
{
MyClass cc;
const MyClass& ccc = cc;
cc.Foo();
ccc.Foo();
}
This will output
Foo
Foo const
In the non-const method you can change the instance members, which you cannot do in the const version. If you change the method declaration in the above example to the code below you will get some errors.
void Foo()
{
counter++; //this works
std::cout << "Foo" << std::endl;
}
void Foo() const
{
counter++; //this will not compile
std::cout << "Foo const" << std::endl;
}
This is not completely true, because you can mark a member as mutable and a const method can then change it. It's mostly used for internal counters and stuff. The solution for that would be the below code.
#include <iostream>
class MyClass
{
private:
mutable int counter;
public:
MyClass() : counter(0) {}
void Foo()
{
counter++;
std::cout << "Foo" << std::endl;
}
void Foo() const
{
counter++; // This works because counter is `mutable`
std::cout << "Foo const" << std::endl;
}
int GetInvocations() const
{
return counter;
}
};
int main(void)
{
MyClass cc;
const MyClass& ccc = cc;
cc.Foo();
ccc.Foo();
std::cout << "Foo has been invoked " << ccc.GetInvocations() << " times" << std::endl;
}
which would output
Foo
Foo const
Foo has been invoked 2 times
The const means that the method promises not to alter any members of the class. You'd be able to execute the object's members that are so marked, even if the object itself were marked const:
const foobar fb;
fb.foo();
would be legal.
See How many and which are the uses of “const” in C++? for more information.
The const qualifier means that the methods can be called on any value of foobar. The difference comes when you consider calling a non-const method on a const object. Consider if your foobar type had the following extra method declaration:
class foobar {
...
const char* bar();
}
The method bar() is non-const and can only be accessed from non-const values.
void func1(const foobar& fb1, foobar& fb2) {
const char* v1 = fb1.bar(); // won't compile
const char* v2 = fb2.bar(); // works
}
The idea behind const though is to mark methods which will not alter the internal state of the class. This is a powerful concept but is not actually enforceable in C++. It's more of a promise than a guarantee. And one that is often broken and easily broken.
foobar& fbNonConst = const_cast<foobar&>(fb1);
These const mean that compiler will Error if the method 'with const' changes internal data.
class A
{
public:
A():member_()
{
}
int hashGetter() const
{
state_ = 1;
return member_;
}
int goodGetter() const
{
return member_;
}
int getter() const
{
//member_ = 2; // error
return member_;
}
int badGetter()
{
return member_;
}
private:
mutable int state_;
int member_;
};
The test
int main()
{
const A a1;
a1.badGetter(); // doesn't work
a1.goodGetter(); // works
a1.hashGetter(); // works
A a2;
a2.badGetter(); // works
a2.goodGetter(); // works
a2.hashGetter(); // works
}
Read this for more information
Blair's answer is on the mark.
However note that there is a mutable qualifier which may be added to a class's data members. Any member so marked can be modified in a const method without violating the const contract.
You might want to use this (for example) if you want an object to remember how many times a particular method is called, whilst not affecting the "logical" constness of that method.
Meaning of a Const Member Function in C++ Common Knowledge: Essential Intermediate Programming gives a clear explanation:
The type of the this pointer in a non-const member function of a class
X is X * const. That is, it’s a constant pointer to a non-constant X
(see Const Pointers and Pointers to Const [7, 21]). Because the object
to which this refers is not const, it can be modified. The type of
this in a const member function of a class X is const X * const. That
is, it’s a constant pointer to a constant X. Because the object to
which this refers is const, it cannot be modified. That’s the
difference between const and non-const member functions.
So in your code:
class foobar
{
public:
operator int () const;
const char* foo() const;
};
You can think it as this:
class foobar
{
public:
operator int (const foobar * const this) const;
const char* foo(const foobar * const this) const;
};
I would like to add the following point.
You can also make it a const & and const &&
So,
struct s{
void val1() const {
// *this is const here. Hence this function cannot modify any member of *this
}
void val2() const & {
// *this is const& here
}
void val3() const && {
// The object calling this function should be const rvalue only.
}
void val4() && {
// The object calling this function should be rvalue reference only.
}
};
int main(){
s a;
a.val1(); //okay
a.val2(); //okay
// a.val3() not okay, a is not rvalue will be okay if called like
std::move(a).val3(); // okay, move makes it a rvalue
}
Feel free to improve the answer. I am no expert
when you use const in the method signature (like your said: const char* foo() const;) you are telling the compiler that memory pointed to by this can't be changed by this method (which is foo here).
Here const means that at that function any variable's value can not change
class Test{
private:
int a;
public:
void test()const{
a = 10;
}
};
And like this example, if you try to change the value of a variable in the test function you will get an error.
The const keyword used with the function declaration specifies that it is a const member function and it will not be able to change the data members of the object.
https://isocpp.org/wiki/faq/const-correctness#const-member-fns
What is a "const member function"?
A member function that inspects (rather than mutates) its object.
A const member function is indicated by a const suffix just after the member function’s parameter list. Member functions with a const suffix are called “const member functions” or “inspectors.” Member functions without a const suffix are called “non-const member functions” or “mutators.”
class Fred {
public:
void inspect() const; // This member promises NOT to change *this
void mutate(); // This member function might change *this
};
void userCode(Fred& changeable, const Fred& unchangeable)
{
changeable.inspect(); // Okay: doesn't change a changeable object
changeable.mutate(); // Okay: changes a changeable object
unchangeable.inspect(); // Okay: doesn't change an unchangeable object
unchangeable.mutate(); // ERROR: attempt to change unchangeable object
}
The attempt to call unchangeable.mutate() is an error caught at compile time. There is no runtime space or speed penalty for const, and you don’t need to write test-cases to check it at runtime.
The trailing const on inspect() member function should be used to mean the method won’t change the object’s abstract (client-visible) state. That is slightly different from saying the method won’t change the “raw bits” of the object’s struct. C++ compilers aren’t allowed to take the “bitwise” interpretation unless they can solve the aliasing problem, which normally can’t be solved (i.e., a non-const alias could exist which could modify the state of the object). Another (important) insight from this aliasing issue: pointing at an object with a pointer-to-const doesn’t guarantee that the object won’t change; it merely promises that the object won’t change via that pointer.
In const objects only const methods can be called. All fielnd in such a method considered as const field.
Last issue has curious effect:
pointer becomes a const pointer int* const, which is not the same as a pointer to const const int*. Thus you can alter the object which pointer points to, but can't make pointer to point to another object.
reference should become a const reference, but it is invariantly a const reference: you can not re-init it to another object. But again you can alter the object which reference refers to.

Confused about constant objects C++

I'm confused about constant objects in C++
When we have passed a constant object/ reference of a const object is that mean that we cannot edit the attribute values of that object ?
or if its not whats the mean or constant in that is it 'refer' object' or 'attributes'
also when we return a constant object
declaring the function like
return_type function_name(parameters) const
{
}
the const keyword is at end of the function is it syntax ? and why if we return a const object shouldn't it be like follows
const return_type function_name(parameters)
{
}
Sorry if its a noob question ;)
This syntax:
return_type function_name(parameters) const
{
}
Indicates that function_name() may be invoked for an instance of the class that is const. It doesn't have any effect on the const-ness of the return value.
const return_type function_name(parameters)
{
}
...indicates that the value being returned from function_name() is const (and says nothing about the const-ness of the object having its member function called.)
When we have passed a constant object/ reference of a const object is that mean that we cannot edit the attribute values of that object ?
Yes. If the function is const, then the function cannot modify any non-mutable fields on the class. (Or call any other non-const method on the class).
and why if we return a const object shouldn't it be like follows
Because the return type can be constant too. Consider the following:
#include <string>
class MyClass
{
std::string data;
public:
void SetData(const std::string& content)
{
data.assign(content);
}
const std::string& GetData() const //Note that the function is const, and so
{ //is the reference it returns.
return data;
}
};
Note that we are returning a const reference to the internal member. If we returned a non const reference, than someone would be able to use the reference to modify the private member of the class, in this case MyClass::data.
Effectively the added const changes the first "hidden" parameter of the method from ClassType * const this to const ClassType * const this.