C++常方法与常对象相关疑问:access函数及强制类型转换逻辑
疑问1解答
access()是Factorial类的公有常成员函数,核心作用是给私有成员变量n提供只读的对外访问接口:
- 类的私有成员
n默认不允许类外代码直接访问,通过这个公有函数可以在不破坏封装性的前提下获取n的值 - 函数末尾的
const限定表示该函数不会修改类的任何成员变量,因此const修饰的类对象也可以调用这个函数,你代码中同为const的Calculate成员函数调用它也是合法的,用来获取n的值参与阶乘运算。
疑问2解答
int* ptr=(int*)&f1;这行是通过强制类型转换拿到const对象私有成员的指针,具体运行逻辑如下:
- 首先
&f1拿到的是const修饰的Factorial对象f1的内存首地址,类型为const Factorial* - 你用C风格的强制类型转换,直接把这个指针强行转换成
int*类型 - 这里利用了当前Factorial类的内存布局特性:类没有虚函数、第一个非静态成员就是int类型的
n,所以对象的首地址和成员n的地址是重合的,转换后的ptr实际上就指向了f1的私有成员n的内存位置 - 后续的
*ptr = n1就是直接修改这块内存的值,绕开了C++的const访问限制和私有成员访问限制,变相给n赋值了。
注意:这个写法是严重不符合C++规范的,属于未定义行为。修改const修饰的对象的内容、直接通过内存地址访问私有成员都是非常危险的操作,只要类的内存布局发生变化(比如加了虚函数、调整了成员顺序)、或者编译器开启了优化,代码大概率会运行出错甚至崩溃。正确的实现应该是给Factorial类新增一个公有的setter成员函数来设置
n的值,不要用这种不符合规范的野路子实现。
内容的提问来源于stack exchange,提问作者Gunner Coins
相关产品推荐
相关产品推荐

