由于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();
}
这完全不足为奇,因为“init”函数的“const”限定符。
但是,以下代码编译并顺利运行,
#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();
}
问题:在第二种情况下,为什么“const”函数(init)可以修改其成员(p)?
答案 0 :(得分:5)
你的C风格演员正在做一个const_cast
(除其他事项外),它允许你获得一个非const对象的可写视图,即使你拥有的只是一个只读视图。
但是,如果你不小心,它可能会破坏(导致未定义的行为)。考虑:
const A a;
int main()
{
a.init();
//a.assign();
a.print();
}
如果您的工具链将a
放入只读内存中,那么在运行时可能会失败。
const
与private
一样,不提供安全性。它是类型系统的一部分,并利用编译器的类型检查器来帮助您捕获编码错误。但是输入信息总是可以用强制转换覆盖。
最后,如果您不想意外抛弃const
,请不要使用C风格的演员表。如果您使用static_cast
或reinterpret_cast
,编译器就会发现错误。