共用数据的保护

el/2024/4/13 14:47:42

C++有不少措施保护数据的安全性,如private保护类的数据成员等。但对于一些共用的数据,如函数实参与形参等,我们可以在不同的场合通过不同的途径访问同一个数据对象。有时不经意的误操作会改变数据的值。

一、常对象

既要使数据能在函数间共享,又要保证它不被任意修改,可以使用const限定即把数据定义为只读的。
在定义对象时使用const限定,称它为常对象

定义的一般形式为:

   类名 const 对象名(实参列表);

或 const 类名 对象名(实参列表);

如: const student stu1;
     student const stu2 (20060102,“李四”,90) ;
1)常对象中的数据成员均是const的,必须要有初值。无论什么情况下,常对象中的数据成员都不能被修改。

2)除了默认构造函数和默认析构函数外,常对象只能调用常成员函数。
如:stu1.num=20060103;//error
   stu1.display( );//error
3)在实际编程中,有时一定要修改常对象中的某个数据成员的值可以将数据成员声明为mutable(可变的)来修改它的值。
声明形式为:
mutable  数据成员类型  数据成员名列表;

如: mutable int num;//可变的数据成员

二、常数据成员

在定义成员时使用const限定,称它为常数据成员

定义的一般形式为:
const  类型名  成员名;
如: const int num;
说明:常数据成员的值,只能通过构造函数的初始化表进行初始化。

三、常成员函数

在定义成员函数时使用const限定,称它为常成员函数。
定义的一般形式为:
返回类型 函数名(形式参数列表) const

{  函数体  }

说明:
1)常成员函数只能引用本类中的数据成员,不能改变其值。
2)无论声明还是定义常成员函数都要加const关键字。常成员函数可以访问const数据成员,也可以访问非const的数据成员。const数据成员可以被const成员函数访问,也可以被非const的成员函数访问。

数据成员

非常成员函数

常成员函数

非常数据成员

允许访问,可以修改

允许访问,不能修改

常数据成员

允许访问,不能修改

允许访问,不能修改

常对象数据成员

不允许访问和修改

允许访问,不能修改

关于常成员函数的说明:
1)在一个类中,如果有些数据成员的值允许修改,另一些数据成员的值不允许修改,可以将一部分数据成员声明为const(常数据成员),使得其值不能被修改。而普通的成员函数可以修改普通的数据成员,但只能访问常数据成员的值。
2)如果要求所有数据成员的值都不允许改变,可以将对象声明为const的(常对象),则只能用const成员函数访问数据成员.且不能修改其值
3)如果定义了一个常对象,只能调用其中的const成员函数,而不能调用非const成员函数。如果需要访问常对象中的数据成员,可将常对象中所有成员函数都声明为const成员函数,但应确保在函数中不会修改对象中的数据成员。
4)常对象中的成员函数不一定是常成员函数。如果在常对象中的成员函数未加const声明,C++把它作为非常成员函数处理。
5)常成员函数不能调用另一个非常成员函数。

四、指向对象的常指针

常指针是const的不能改变指向,但常指针所指向的对象却不一定是const的

指向对象的常指针定义形式:

类名 *const 指针变量名;
如: student stu;
      student *const p= &stu ;
通常,使用常指针作为函数的形参,目的是不允许在函数执行过程中改变指针变量的值,使其始终指向原来的对象。如果在函数执行过程中试图修改常指针形参的值,就会出现编译错误。

指向常对象的指针变量定义形式:
const  类名  *指针变量名;
如: const student*p;//指针变量指向的对象为const

说明:指向常对象的指针变量,是不能通过它改变所指向的对象的值,但是指针变量本身的值是可以改变的,因此可以在定义时不初始化。

指向对象的常指针与指向常对象的指针的区别:
student *const p =&d;
const student *p;
1)如果一个对象已被声明为常对象,只能用指向常对象的指针变量指向它。

2)如果定义了一个指向常对象的指针变量,即使它指向一个非const的对象,其指向的对象也是不能通过指针来改变的。

3)指向常对象的指针作函数形参,目的是在保护形参指针所指向的对象,使它在函数执行过程中不被修改。使用常指针作为函数的形参,目的是不允许在函数执行过程中改变指针变量的值,使其始终指向原来的对象。如果在函数执行过程中试图修改常指针形参的值,就会出现编译错误。

五、对象的常引用

在C++程序中,经常用对象的常指针和常引用作函数参数。这样既能保证数据安全,使数据在函数中不能被随意修改,在调用函数时不必传递实参对象的副本,大幅减少函数调用的空间和时间的开销。

对象常引用定义形式:
const  类名  &引用变量名;
 


http://www.ngui.cc/el/4994640.html

相关文章

对象的动态建立和释放,赋值和复制

一、对象的动态建立和释放 利用new运算符可以动态地分配对象空间,delete运算符释放对象空间。 动态分配对象的一般形式: new 类名; 用new运算符动态分配得到的对象是无名的,它返回一个指向新对象的指针的值,即所分配的内存单元的起始地址。程序通过这…

文件查看命令和用户管理命令

文件查看命令 cat 1.用于查看文件数据 cat a.txt 2.合并文件 cat a.txt b.txt > c.txt 3.向文件中写入数据 cat > d.txt 这样写入数据有一点需要注意:cat > d.txt 输入数据时,会先将d.txt中的数据清空。 cat >> d.txt 向文件的末…

左值右值,柔性数组

一、右值、左值 在c中,左值就是可以被赋值的,右值就是不可被赋值的 在c11标准下: 所有的值必属于左值、右值两者之一。 右值分为纯右值和将亡值 在C11中可以取地址的、有名字的就是左值,反之,不能取地址的、没有名字的就是右值&a…

C++统一初始化和输入输出

一、c统一初始化 C语言中初始化一个量只有赋值语句这一种办法 c中初始化方式比较多 #include<iostream> using namespace std;int main() {int a 10;//c语言中初始化只有赋值语句这一种方法//以下都是c初始化的方法int b(10);//这样有点像对象初始化的形式int c{ 10 …

如何判断是以c++方式编译还是c方式编译

如何判断是以c方式编译还是c方式编译&#xff1f; 通过宏判断&#xff0c;c方式编译有宏 _cplusplus c中没有_cplusplus 在程序中可以利用开关语句&#xff08;探测宏&#xff09; #ifdef _cplusplusprintf("c"); #elseprintf("c"); #endif

关于log4j和slf4j的使用说明

1.log4j是日志类基础&#xff0c;slf4j需要依赖他&#xff0c;同时还需要一个log4j和slf4j的媒介来整合他们俩。简而言之&#xff0c;log4jslf4j&#xff08;slf4j--log4j&#xff09;三位一体才能爽歪歪&#xff01; 2.三者的版本如何搭配选择&#xff1f;答案是&#xff0c;…

通过jug 2.0.jar的成功下载的猜想

1.maven的配置为以下方式时&#xff0c;下载出错 <dependency> <groupId>org.safehaus.jug</groupId> <artifactId>jug</artifactId> <version>2.0.0</version> </dependency> 2.maven以以下配置时&#…

关于项目突然启动缓慢或者停留在Initializing Spring FrameworkServlet xx的原因

1.原因很简单&#xff0c;因为你的项目里出现了断点&#xff0c;所以加载项目很慢&#xff0c;如果你给tomcat设置启动时间了&#xff0c;那么通tomcat就启动失败&#xff01; 2.至于你为什么仔细检查了项目&#xff0c;都没有发现断点&#xff0c;原因很简单&#xff0c;你是…

hql出现could not initialize proxy - no Session的另外一个原因

1.重中之重的原因是表中有非空字段&#xff0c;但是你save or update之时没有注意这个&#xff0c;然后才报了这个错误&#xff01; 2.当然还有就是延迟加载设置的策略&#xff0c;这个你可以搜索别的文章看一看如何设置

微信爬虫机器人的坑篇之无法获取群组的解决方案

1.微信爬虫实现的方案&#xff0c;详情请参考此链接&#xff0c;作者已经说得很明白了https://blog.csdn.net/wonxxx/article/details/51787041 2.但是如果你根据作者这些分析进行机器人操作的话&#xff0c;其中 获取好友列表&#xff08;webwxgetcontact&#xff09;这个功能…