归纳编程学习的感悟,
记录奋斗路上的点滴,
希望能帮到一样刻苦的你!
如有不足欢迎指正!
共同学习交流!
🌎欢迎各位→点赞 👍+ 收藏? + 留言?📝
一滴汗珠万粒粮,万粒汗珠谷满仓!
一起加油!
目录
💦例:在主函数中定义数组,存放班级学生的分数,定义一个函数统计班级分数平均值。
????????数据隐藏保证了数据的安全性,但有时我们又需要进行数据共享,各种形式的数据共享对数据的安全性造成了不同程度的破坏。为了既实现数据共享又能保护数据安全,通常我们会考虑以下几种方式: (1)对于既需要共享又不能更改的数据应该声明为常量(2)将数据以及操作数据的函数封装成类,类中的函数可以随意访问类中的数据,从而实现共享。通过设定数据成员为私有或者保护,可以把共享限定在类的内部,对类外的函数来说,数据成员是隐藏的。下面我们主要介绍通过声明常量保护数据。
? ? ? ? 一个对象被声明为常对象后,其数据成员的值在对象整个生存期内不能被改变。因此,定义常对象时必须对其进行初始化,而且不能被更新。常对象定义格式如下:
const 类型说明符 对象名;
也可以把 const 关键字写在对象名前面,第一种写法更容易被编程人员接受。对于基本数据类型中的常量,C++语法对其提供了保护措施,即必须在定义时进行初始化,初始化后值不能被改变。
????????对象不是变量,不能通过简单赋值更新其值。那么,如何保护常对象的值不被改变呢?改变对象的数据成员的值有两种方法:
(1)直接对对象数据成员进行访问赋值,由于限定对象为常对象,常对象的数据成员等同于常量,因此语法会限制其不能被赋值;
(2)通过对象调用类的成员函数,在成员函数中可以对数据成员值进行修改。由于无法确定成员函数是否会修改数据成员,因此只能从语法上限定常对象不能调用普通的成员函数,以防止数据成员在成员函数中被修改。
????????语法上规定常对象不能调用类中的普通成员函数,没有任何对外的接口可以使用,常对象还有什么用处呢? 常成员函数就是专为常对象设计的。也就是说常对象能调用类中的常成员函数。常成员函数声明的格式如下:
类型 函数名(形参表) const;
注意以下几点。
?????????语法上限定常对象只能调用常成员函数,但是不限制一般对象调用常成员函数。t果有两个同名的成员函数,一个声明为 const 类型,那么在理论上,一般对象都可以调用这两个成员函数。这会造成两个重载的函数都可以被匹配,此时编译器就会为一般对象选择最合适的重载函数——不带 const 关键字的函数。
#include<iostream>
using namespace std;
class R{
private:
int R1,R2;
public:
R(int r1,int r2):R1(r1),R2(r2){ };
void display();
void dispaly() const;//常成员函数,const可实现函数重载
};
void R::display(){
cout<<R1<<"-"<<R2<<endl;
}
void R::dispaly()const{
cout<<R1<<"+"<<R2<<endl;
}
int main(){
R a(50,40);//声明普通对象a
a.display();//a调用普通成员函数
const R b(30,40);//声明常对象b
b.dispaly();//b调用常成员函数
return 0;
}
????????常成员函数不能更新对象的数据成员,也不能调用该类中没有用 const 修饰的普通成员函数;常对象必须被初始化,且不能被更新。常对象只能调用它的常成员函数,而不能调用其他普通成员函数。正因如此,在实际应用中,往往把数据成员不可修改的函数设置为常成员函数,把属性不可修改的对象也设置为常对象。常对象只能调用常成员函数,这种调用方式实现了对数据成员的保护。?
?????????也可将类的成员数据声明为常量,使用 const 限定的数据成员为常数据成员。如果一个类中说明了常数据成员,那么任何函数中都不能对该成员赋值。只能在构造函数中对其进行初始化。且常数据成员必须利用构造函数所附带的初始化列表进行初始化,而不能在构造函数中直接用赋值语句为其进行赋值。
#include<iostream>
using namespace std;
class A{
private:
int w,h;
const int color;
public:
A(int x,int y,int c):w(x),h(y){ };
void display(){
cout<<"("<<w<<","<<h<<")"<<"color is :"<<color<<endl;
}
};
int main(){
A P(20,30,0);
P.display();
return 0;
}
?????????为了将批量的数据传递给函数,我们通常会将成批的数据存放在数组中,然后将数组名传给函数。函数在得到成批的数据后,就可以进行需要的操作。很多时候我们希望把数据传递给函数使用,同时不希望函数修改数据,以降低引起数据安全问题的风险。
#include<iostream>
using namespace std;
float getAverage(float *p,int len){
float score=0;
for(int i=0;i<len;i++){
score+=p[i];
}
return score/len;
}
int main(){
float score[10]={89,78,79,87,86,84,95,97,79,80};
cout<<getAverage(score,10)<<endl;
return 0;
}
?函数如果只有使用数据而无修改数据的必要,而形参类型为指针或引时,一定要将形参声明为常指针或常引用。将 getAverage 形参类型声明为常指针的形式如下:
float getAverage(const float *p,int len);
?????????如果在声明引用时用 const 限定,被声明的引用就是常引用。在常引用中被引用的对象不能被更新。与常指针用法类似,常引用主要用来作为形参,通过 const 限定形参后在函数里面就不能意外地发生对实参修改的事件。
#include<iostream>
#include<cmath>
using namespace std;
class Point{
private:
double x,y;
public:
Point(double px,double py):x(px),y(py){ };
friend double dist(const Point& p1,const Point & p2);
void display(){
cout<<"("<<x<<","<<y<<")"<<endl;
}
};
double dist(const Point& p1,const Point & p2){
double m=p1.x-p2.x;
double n=p1.y-p2.y;
return sqrt(m*m+n*n);
}
int main(){
Point p1(4,5),p2(6,8);
cout<<"两点:"<<endl;
p1.display();
p2.display();
cout<<"距离为:"<<dist(p1,p2)<<endl;
return 0;
}
????????以上就是我对C++共享和保护——(4)保护共享数据的理解,希望本篇文章对你有所帮助,也希望可以支持支持博主,后续博主也会定期更新学习记录,记录学习过程中的点点滴滴。如果有不懂和发现问题的小伙伴,请在评论区说出来哦,同时我还会继续更新对C++共享和保护的理解,请持续关注我哦!!!?