Reputation: 18870
I have the following codes that failed compilation due to invalid conversion from ‘const int*’ to ‘int*’ [-fpermissive]
#include <iostream>
#include <stdlib.h>
using namespace std;
#define N 3
void f(int *p)
{
*p=8;
}
class A
{
private:
int a;
public:
void init() const;
void print() const {cout<<a<<endl;}
};
void A::init() const
{
f(&a);
}
int main()
{
A a;
a.init();
a.print();
}
This is not surprising at all because of the "const" qualifier of the "init" function.
However, the following codes compiled and ran smoothly,
#include <iostream>
#include <stdlib.h>
using namespace std;
#define N 3
void f(void **pp)
{
*pp = new int[N];
}
class A
{
private:
int * p;
public:
void init() const;
void assign() {for (size_t i=0; i<N; i++) p[i]=i;}
void print() const {for (size_t i=0; i<N; i++) cout<<p[i]<<" "; cout<<endl; }
~A(){delete [] p;}
};
void A::init() const
{
f((void**)&p);
}
int main()
{
A a;
a.init();
a.assign();
a.print();
}
Question: in the second case, why a "const" function (init) can modify its member (p)?
Upvotes: 0
Views: 198
Reputation: 283664
Your C-style cast is doing a const_cast
(among other things), which allows you to obtain a writable view of a non-const object even if all you had was a read-only view.
However, it can break horribly (cause undefined behavior) if you aren't careful. Consider:
const A a;
int main()
{
a.init();
//a.assign();
a.print();
}
This could fail spectacularly at runtime, if your toolchain put a
into read-only memory.
const
in C++, like private
, does not provide security. It is part of the type system, and leverages the compiler's type checker to help you catch coding errors. But typing information can always be overridden with casts.
Finally, if you don't want to accidentally cast away const
, don't use C-style casts. If you used static_cast
or reinterpret_cast
the compiler would have caught the mistake.
Upvotes: 5