This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
What is the meaning of a const at end of a member function?
about const member function
I found one function prototype as under:
const ClassA* ClassB::get_value() const
What does the above statement signify? Can I change the member of ClassA object?
The first const means what it returns is a pointer to const A. So no, you can't change what it returns (unless you cast away the const-ness, which will give undefined behavior if the object it returns is actually defined as const, rather than returning a const pointer to an object that itself wasn't defined as const).
The second const means that get_value can't change any of the (non-mutable) state of the ClassB on which it's invoked (among other things, it's transitive, so ClassB::get_value can only call other member functions that are also const-qualified).
No.
The ClassA pointer returned by that function is marked const. That means that you should not change any of its values.
It won't be impossible to change the values because there are various ways to get around a const marking, but you are clearly not meant to be changing it.
What does the above statement signify? Can i change the member of ClassA object.
get_value is a const member function of ClassB so it cannot modify any non-mutable data members of ClassB inside its definition. But it can however modify members of ClassA
For example the following compiles (leaks memory but that is not much of a concern here)
struct A{
int x;
};
struct B
{
const A* get_value() const
{
A *p= new A;
p->x = 12;
return p;
}
};
get_value() is a read-only function that does not modify the ClassB object for which it is called. It returns a read-only pointer to a ClassA object. You can modify the object pointed to by this object by casting away its constness using const_cast. But the ideal thing to do is to make a copy of this object and mutate that.
Related
Today I found out that code like that works. That sounds really strange to me, because as far as I always knew you can't modify any of members from const member function. You actually can't do it directly, but you can call non-const member function. if you mark member function as const that means that this pointer passed to the function is pointing to const object, then how non-const member function is called in the example bellow?
#include <iostream>
class X
{
public:
void foo() const
{
ptr->bar();
}
void bar() {}
private:
X * ptr;
};
int main()
{
}
Your member variable is not X, but pointer to X. As long as foo does not modify the pointer, it can be const.
When you have a pointer member, then the pointer is const in a const method. You won't be allowed to change the address stored in the pointer. But you can change the pointee all you like.
It's the difference between
X* const cannot_change_pointer; //this is how top-level const applies to pointers
const X* cannot_change_pointee;
What's even more interesting is that const on a method has no effect whatsoever on reference members for the same reason (a const method would only prevent you making a reference refer to something else which can't be done with a reference anyway).
That's seems perfectly OK. The call to foo does not modify the ptr member. Hence, the constness of foo is respected.
my 2 cents
I know a const method cannot modify the object from which it is called. Look at this code:
class A{
int a;
public:
void f(A & a_) const {
a_.a=5;
};
};
int main(){
A x;
x.f(x);
return 0;
}
Why does this code compile? Why can I even assign a reference to a non const object of the same class, when declaring the method as constant? In general how can the compiler check all the possible situations in which the function could modify the object?
I know a const method cannot modify the object from which it is called.
This is an oversimplification, and slightly inaccurate.
A const function merely means that the implicit this pointer is a pointer to const.
Why does this code compile?
Because it is well-formed.
Why can I even assign a reference to a non const object of the same class, when declaring the method as constant?
Because constness of the function does not affect what objects you can modify through a reference.
In general how can the compiler check all the possible situations in which the function could modify the object?
The compiler simply does not make such checks.
A const member function cannot modify the object from which it is called using the "implicit" this parameter. f(...) is (ignoring member visibility) equivalent to the free function
void f(const A* this, A& _a) {
_a.a = 5;
}
If you pass the same object as a non-const pointer or reference, you are still allowed to modify it.
I have a ClassA that has a private: vector<ClassB> vec. I'm filling the vector up in ClassA::fillVec().
Now i'd like to return the vector(by reference? so no copying) and i'd also like forbid any further changes using const.
What still confuses me is the syntax. What i have so far is
const std::vector<ClassB> &ClassA::fillVec(...) const {}
But I don't know if that is right. And even if it's right, I found this solution on the internet, so if anyone could explain why the two const
The first const means that the return type is const reference i.e. the vector may not be modified through the reference.
The const at the end means that the member function is not allowed to modify the (ClassA) object. It is therefore allowed to call that method on a const ClassA instance. This of course contradicts with the purpose of the function assuming it's supposed to modify the member; it should therefore not be const.
You want to return a const reference to prevent the user changing it; but the function itself can't be const, since it modifies a class member.
const std::vector<ClassB> &fillVec(<parameters>);
^ ^
const return value no const here
You would use the second const on member functions that aren't supposed to modify the object they're called on.
Today I found out that code like that works. That sounds really strange to me, because as far as I always knew you can't modify any of members from const member function. You actually can't do it directly, but you can call non-const member function. if you mark member function as const that means that this pointer passed to the function is pointing to const object, then how non-const member function is called in the example bellow?
#include <iostream>
class X
{
public:
void foo() const
{
ptr->bar();
}
void bar() {}
private:
X * ptr;
};
int main()
{
}
Your member variable is not X, but pointer to X. As long as foo does not modify the pointer, it can be const.
When you have a pointer member, then the pointer is const in a const method. You won't be allowed to change the address stored in the pointer. But you can change the pointee all you like.
It's the difference between
X* const cannot_change_pointer; //this is how top-level const applies to pointers
const X* cannot_change_pointee;
What's even more interesting is that const on a method has no effect whatsoever on reference members for the same reason (a const method would only prevent you making a reference refer to something else which can't be done with a reference anyway).
That's seems perfectly OK. The call to foo does not modify the ptr member. Hence, the constness of foo is respected.
my 2 cents
String::~String() {
std::cout<<"String()" <<std::endl;
}
I wonder if this implementation of destructor is valid?
And another question about const member function qualifier, I know the const function can not change the variables in this class, it just read-only. If there is no other weird questions about it, I think I can understand it, but I saw some questions as following:
It allows the invocation of a non-const member function for the object pointed to by this
It guarantees that only mutable member variables of the object pointed to by this can be changed
It ensures that all constants remain invariable
It prevents inheritance
It allows changes to the state of the object pointed to by this
Based on my understanding, it is very hard to check which one is right, so I guess all of them are wrong?
The destructor is technically just another function, there doesn't seem anything wrong syntactically with this destructor to me, so it seems valid
That is all there is to const member functions, you cannot modify the data. These functions are automatically invoked by a const instance of the class. So if you have two functions with the same signature except for const-ness, it will chose the const version for const instances, and for non-const instances, it will depend on how you use it that determines which version is invoked
a) you cannot invoke non-const member functions within a const member function
b)Correct
c) correct
d) i'm unsure what you mean by preventing inheritance. IF you declare a function as virtual, const or not, it is inherited and can be overridden by subclasses
e) in const member functions, all data is considered const, unless declared a mutable.
Yes, that is a valid destructor.
const does not prevent inheritance. Nor does it bring about invariant behavior in the class's methods.
This question is actually multiple questions, though.
I recommend reading C++ FAQS.
I wonder if this implementation of destructor is valid?
There is nothing wrong with the destructor. But the question is: is that all you want to do in the destructor? Destructor is usually used to free the resources object holds when its alive; so it should free them when its going to die, so that others can use them. If it doesn't free them, then those resources will not be used by others as long as the program runs. Such a situation is usually referred to as Resource Leak, and if the resource is memory, its called Memory Leak.
Regarding question 2.
A nice way to think of member function cv qualifiers is to think of them as qualifiers on the 'this' pointer.
For example, if we wrote some C++ code in C:
class A
{
public:
void f1 ();
void f2 () const;
private:
int i;
};
This is the same as the following C code:
struct A
{
int i;
};
void f1 (A * const this); // Non const member
void f2 (A const * const this); // Const member
Another important thing to understand is that when you refer to a non static data member of a class, (*this). is implicitly added to it:
void A::f1 ()
{
i = 0; // This and the next line have the same meaning
(*this).i = 0;
}
When the member function is const, the this pointer is declared as pointing to a const object:
void A::f2 () const
{
(*this).i = 0; // Error '*this' is const, so cannot modify (*this).i
}
One of the conclusions from this, and something that people sometimes find is surprising, is that a const member function can still modify data pointed to by a member pointer. For example:
class A
{
public:
void f () const
{
*i = 0;
}
private:
int * i;
};
This looks wrong, but it's actually fine. (*this).i is const and so you would not be able to change what i points to, but i is still a pointer to a non const int and so we can modify the value pointed to by i.