指针解封装,你必须知道的“初级简单解法”
c语言之所以被认为强大,以及其自由性,很大部分体现在其灵活的指针运用上。
所以这里就跟大家分享一下指针的强大之处,
通过它来修改私对象成员值,不管是类的、结构体的还是大部分其他的
我们都知道当一个类或结构体的成员是公有的时候,我们可以通过对象调用修改其成员值
以结构体为例,如下:
#include<iostream>
using namespace std;
//定义结构体
struct Student{
int age; //年龄
char ssex; //性别
double score; //得分
};
int main()
{
Student stu; //创建对象
stu.age = 18; //对象调用赋值
stu.ssex = 'F'; //对象调用赋值
stu.score = 90.00; //对象调用赋值
while (1);
}
而当结构体成员属性为私有private的时候,我们就没办法运用上面方法
那要修改结构体Student的对象成员值应该怎么办呢,这时就可以运用指针来“解除”结构体的私有封装,
这里有个前提,那就是要知道你的对象是什么,如上面的整数型 age,字符型ssex,双精度浮点型double等等,如下,把结构体Student的age,ssex,double成员对象变为私有,在主函数main中通过定义指针变量p来修改(详细过程请看下面代码),这里顺便在结构体中定义了一个公有成员函数来显示结构体age,ssex,double私有成员的值
代码如下:
#include<iostream>
#include<Windows.h>
using namespace std;
struct Student{
private:
int age; //年龄
char ssex; //性别
double score; //分数
public:
void show() //定义公有成员函数,显示私有成员函数值
{
cout << endl;
cout << "----修改值验证----";
cout << endl << endl;
cout << "年龄:" << age << ' ';
cout << "性别:" << ssex << ' ' << "成绩:";
printf("%.2lf", score);
/*附:cout跟printf是不同的,cout输出float或double,
是会将小数点后非有效数字的0去掉的,而printf里面以%f输出规定是以6位小数输出,
不管是不是有效数字,这里用printf是为表面double类型的score确实被修改了*/
}
};
int main()
{
SetConsoleTitle("修改私有成员值"); //修改窗口名,头文件Windows.h
Student stu;
int *p;
p = (int*)&stu; //p指向stu.age内存首地址 (int*)为强制类型转换
*p = 20; //修改stu.age值
p++; //p地址偏移,指向stu.ssex
*(char*)p = 'F'; //修改stu.ssex值
p++; //p地址继续偏移,指向stu.score
*(double*)p = 99.00; //修改stu.score值
stu.show(); //调用公有成员函数验证私有成员age,ssex,score值确实被修改了
while (1);
}
修改过程一般需要用到强制转换,因为结构体的成员对象与指针变量p类型不同==
修改后的结果:
对待类的私有成员方法相同是一样的,只是在这里用结构体比较好让大家理解与吸收,理解后可以自己用类试试嘿嘿
另外得提一点,就是不同类型变量占不同的大小内存块,如int占四个字节内存块,double占八个字节内存块,在结构体或类中用p指向变量首地址后,用p++偏移内存,
但在结构体或类外,相同栈内存及变量类型相同才能偏移,且指针的偏移运算不同
如int类型偏移为 p-=3即右移3*sizeof(int)个内存,double 好像为p-=6,其他的具体的可以查阅相关资料
这里以相同类型的整型给大家示例下:
#include<iostream>
using namespace std;
int main()
{
int n = 50;
int m = 60;
int*p = &n;
p-=3;
*p = 600;
cout << "n:" << n << " " << "m:" << m;
while (1);
}
运行结果为:
111有没有觉得很神奇,赶快亲自动手感受一下吧!