I don't understand why I get error with che const at the end of my method. The method print doesn't change any class member, right?
class Hello{
public:
int get_member() {return member_;};
void print() const {
cout<<get_member()<<endl;
};
private:
int member_;
};
The error message is:
error passing "const Hello" as "this" argument of 'int Hello:: get_member()' discards qualifiers [-fpermissive]
int get_member() const {return member_;}
Should fix it. You can't call a non-const member from a const member as it breaks the 'promise' of const. If you could there would be no guarantee that the object isn't modified during the call.
Related
The example generates the error
the object has type qualifiers that are not compatible with the member
function
and I can't figure out why.
A.h
class A {
public:
void f2(XXX* ..) const;
protected:
const vector<XYZ> f(){return m;}
vector<XYZ> m;
}
A.cpp
void A::f2(XXX* ..) const
{
const vector<XYZ>& P= this->f(); // Here I get this error as well
}
Can someone explain me what I've done wrong?
Thanks.
You can't call a non-const function from a const function. This means that f needs to be const qualified as well:
const std::vector<XYZ> f() const { return m; }
otherwise you can't call it from f2.
The member is non const, and the member's member function is non const, when it is called on a const member function, it will generate an error, complains about:
error: passing 'const foo' as 'this' argument discards qualifiers [-fpermissive]
code:
// this class is in library code i cannot modify it
class CWork {
public:
const string work(const string& args) { // non const
...
return "work";
}
};
// this is my code i can modify it
class CObject {
private:
CWork m_work; // not const
public:
const string get_work(const string& args) const { // const member function
return m_work.work(args); // error here
}
};
Why is this and how to fix this?
Compiler is g++ 5.3.1.
Inside a const method the object (*this) and hence all its members are const. Think about it, if this wasnt the case then an object being const would not mean anything.
Thus m_work is const inside get_work and you can only call const methods on it.
Make work also a const method. There is no apparent reason to make it not const and by default you should make methods const. Only when you need to modify the object make them non-const.
it's in library i cannot change it.
In that case you are out of luck. You can only make get_work non const too, because work seems to modify m_work hence modifies your CObject which you cannot do in a const method.
I don't understand why this piece of code won't compile.
I get following error in line return source->GetA();
cannot convert 'this' pointer from 'const class FooStruct' to 'class
FooStruct &'
If I remove the const keyword it compiles fine.
class FooStruct
{
int a;
public:
int GetA() {return a;};
int Bar(const FooStruct *source);
};
int FooStruct::Bar(const FooStruct *source)
{
return source->GetA();
}
The code itself doesn't make sense. It has been stripped down from some real code and its only purpose is to illustrate the problem.
It is because of this line:
return source->GetA();
Here you are trying to execute GetA function on the pointer that you got. If the pointed object is const, the function must also be const, because:
Both const and non-const functions can be executed on non-const objects
Only const functions can be executed on const objects.
It is a good idea to mark all the functions that do not modify the state of the object as const, so they can be used on const objects (e.g. in functions that accept const T & as a parameter).
So in your case, the class should look like:
class FooStruct
{
public:
int GetA() const {return a;}
};
The function GetA itself needs to be marked const:
int GetA() const {
return a;
}
This then allows a const source* pointer to call that function.
Given the code below:
class A
{
public:
A(): value( 0 ) {}
int* get()
{
return &value;
}
const int& get() const
{
return value;
}
private:
int value;
};
int main()
{
A a;
const int& ref_value = a.get();
}
results in the following compilation error:
prog.cpp: In function 'int main()':
prog.cpp:23:35: error: invalid conversion from 'int*' to 'int'
const int& ref_value = a.get();
^
It seems that the overloaded get() method with const modifier does get ignored completely and the compiler sees only the non-const definition of it. It is somehow understandable since the a object is not constant. One solution would be to make the a object constant. Though there are other two solutions that makes the code compileable:
Change the signature of the const get() method by different name or other parameters added.
int* get();
const int& get_changed() const; <-- this gets called
Change the non-const get() method to return a reference instead pointer.
int& get(); <-- this gets called
const int& get() const;
though with
int* get();
const int& get() const;
we have a compiler error.
What puzzles me is the reason behind all of these behavior.
When you have both a const and non-const overload of the same function with the same parameters, which one gets called depends only on the constness of the object on which you're invoking the function. So invoking on a non-const a must call the non-const overload.
It's exactly the same situation as this:
void foo(int *p);
void foo(const int *p);
int main()
{
int i;
const int ci;
foo(&i); // Calls the first overload
foo(&ci); // Calls the second overload
}
A const-qualified function can be called on a non-const-qualified object, but that requires a "nonconst to const" conversion. If there's an overload which doesn't require such a conversion (is a better match), it will be preferred.
The reason is that the compiler can't do overload resolution based on a different return type.
Only the function signature is taken into account for overload resolution. And the function signature consists only of the function name, the parameters, and the cv qualifiers - not the return type.
This question already has answers here:
Meaning of 'const' last in a function declaration of a class?
(12 answers)
Closed 7 years ago.
In C++ sometimes I see declarations like below:
return_type function_name( datatype parameter1, datatype parameter2 ) const
{ /*................*/}
What does this const type qualifier exact do in this case?
The const qualifier at the end of a member function declaration indicates that the function can be called on objects which are themselves const. const member functions promise not to change the state of any non-mutable data members.
const member functions can also, of course, be called on non-const objects (and still make the same promise).
Member functions can be overloaded on const-ness as well. For example:
class A {
public:
A(int val) : mValue(val) {}
int value() const { return mValue; }
void value(int newVal) { mValue = newVal; }
private:
int mValue;
};
A obj1(1);
const A obj2(2);
obj1.value(3); // okay
obj2.value(3); // Forbidden--can't call non-const function on const object
obj1.value(obj2.value()); // Calls non-const on obj1 after calling const on obj2
$9.3.1/3 states-
"A nonstatic member function may be declared const, volatile, or const volatile. These cvqualifiers affect the type of the this pointer (9.3.2). They also affect the function type (8.3.5) of the member function; a member function declared const is a const member function, a member function declared volatile is a volatile member function and a member function declared const volatile is a const volatile member function."
So here is the summary:
a) A const qualifier can be used only for class non static member functions
b) cv qualification for function participate in overloading
struct X{
int x;
void f() const{
cout << typeid(this).name();
// this->x = 2; // error
}
void f(){
cout << typeid(this).name();
this->x = 2; // ok
}
};
int main(){
X x;
x.f(); // Calls non const version as const qualification is required
// to match parameter to argument for the const version
X const xc;
xc.f(); // Calls const version as this is an exact match (identity
// conversion)
}
It means that it doesn't modify the object, so you can call that method with a const object.
i.e.
class MyClass {
public:
int ConvertToInteger() const;
};
Means that if you have
const MyClass myClass;
you can call
int cValue = myClass.ConvertToInteger();
without a compile error, because the method declaration indicates it doesn't change the object's data.