用结构体数据的安全性得不到保证。
使用类对数据进行封装,只能通过函数修改类中的数据
(1)类的定义
class 类名 { private: protected: public: };
private:定义私有成员,只能被类本身的成员函数和友元访问。派生类和其他类均不能访问。若数据没有指明类型,默认为私有。
public:定义公有成员,可被程序中任何代码访问。
protected:定义保护成员,能被本身成员函数,友元,派生类访问。
(2)成员函数的定义
a、在类中定义
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; class Student { private: string Name; float Phi,Math,Ave; public: void set(string name,float phi,float math) { Name=name; Phi=phi; Math=math; } void Average() { Ave=(Phi+Math)/2; } void Display() { cout<<Name<<" "<<Phi<<" "<<Math<<" "<<Ave; } }; int main() { Student stud; stud.set("zhangsan",90,100); stud.Average(); stud.Display(); return 0; }
b、在类外定义
(考虑到有些函数复杂,在类内写不好看)
先在类内声明,然后在类外定义的形式是
函数返回值类型 类名 ::函数名称()
{}
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; class Date { private : int year,month,day; public: void setDate(int,int,int); bool IsLeap(); void print() { cout<<year<<" "<<month<<" "<<day<<endl; } }; void Date::setDate(int n,int y,int r) { year=n;month=y;day=r; } bool Date::IsLeap() { if(year%400==0||year%4==0&&year%400) return true; return false; } int main() { Date dt; dt.setDate(2019,11,22); if(dt.IsLeap()) cout<<"yes\n"; else cout<<"no\n"; dt.print(); return 0; }
(3)成员的访问
a、对于数据成员的访问
对象名.成员名 对象指针名->成员名 (*对象指针名).成员名
b、对于成员函数的访问
对象名.成员函数名(参数表) 对象指针名->成员函数名(参数表) (*对象指针名).成员函数名(参数表)
#include<iostream> #include<cstdio> using namespace std; class Student { private : string name; float Math,Phi,Ave; public: void setDate(string nam,float math,float phi) { name=nam; Math=math; Phi=phi; } void Average() { Ave=(Math+Phi)/2; } void print() { cout<<name<<" "<<Math<<" "<<Phi<<" "<<Ave<<endl; } }; int main() { Student stu,*stud; stud=&stu; //一开始我没定义 stu,直接定义个指针用了,这样不行。 stud->setDate("zhangsan",100,90); stud->Average(); stud->print(); return 0; }
#include<iostream> #include<cstdio> using namespace std; class Student { private: string Name; int Phi,Math; public: void setDate(); void print() { cout<<Name<<" "<<Phi<<" "<<Math<<endl; } }; void Student::setDate()//在类作用域内,直接使用即可访问 { cin>>Name>>Phi>>Math; } int main() { Student stud; stud.setDate(); stud.print(); return 0; }
(4)构造函数
构造函数就是对类内的数据初始化,定义一个类的对象时自动调用,如果不写构造函数,就调用系统默认的构造函数。
性质:与类名相同 无返回值 可以重载
#include<iostream> #include<cstdio> using namespace std; class Cuboid //长方体类 { private: int length,width,height; public: Cuboid();//无参构造函数 Cuboid(int,int,int);//有参构造函数 int volume();//计算体积 }; Cuboid::Cuboid() { length=width=height=1; } Cuboid::Cuboid(int l,int w,int h) { length=l; width=w; height=h; } int Cuboid::volume() { return length*width*height; } int main() { Cuboid cuboid1; cout<<"cuboid1的体积为:"<<cuboid1.volume()<<endl; Cuboid cuboid2(10,20,30); cout<<"cuboid2的体积为:"<<cuboid2.volume()<<endl; return 0; }
#include<iostream> #include<cstdio> using namespace std; class Cuboid { private: int h,w,l; public: /* Cuboid(int hh=10,int ww=20,int ll=30)另一种写法 { h=hh;w=ww;l=ll; }*/ Cuboid(int hh=10,int ww=20,int ll=30);//声明时有默认参数 int volume() { return h*w*l; } }; Cuboid::Cuboid(int hh,int ww,int ll)//不用再写默认参数 { h=hh; w=ww; l=ll; } int main() { Cuboid cuboid1; cout<<cuboid1.volume()<<endl; Cuboid cuboid2(1); cout<<cuboid2.volume()<<endl; Cuboid cuboid3(1,2); cout<<cuboid3.volume()<<endl; return 0; }
也可以这样初始化
Cuboid(int h,int w,int len):height(h),width(w),length(len){}
(5)拷贝构造函数
拷贝构造函数的名称与类名一致,函数的形式参数是本类型的一个引用变量。
Sample (Sample &S);
对象1=对象2 //对象1和对象2必须是同一个类
将一个对象的非静态数据成员的值一一赋值给另一对象的对应成员。
Sample S2(S1);
Sample S2=S1;两者等价
a、
#include<iostream> #include<cstdio> using namespace std; class Sample { private: int data; public: Sample(int dt) { data=dt; } void print() { cout<<data<<endl; } }; int main() { Sample s1(100); Sample s2=s1; s2.print(); }
b、自定义拷贝构造函数 并不是一一赋值
#include<iostream> #include<cstdio> using namespace std; class Sample { private: int a,b,c,d; public: Sample(int aa,int bb,int cc,int dd) { a=aa;b=bb;c=cc;d=dd; } Sample(Sample &S) { a=S.a;b=S.b;c=S.c; d=S.d+1; } void print() { cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl; } }; int main() { Sample dt1(1,2,3,4); Sample dt2=dt1; //Sample dt2(dt1); dt2.print(); return 0; }
(6)析构函数
作用在对象脱离作用域时释放相关资源,清理善后工作。
析构函数名和类名相同只是在函数名前面加~符号
无参数 无返回值 只能有一个析构函数 不写虚构函数调用系统自己的
#include<iostream> #include<cstdio> using namespace std; class Cstudent { private: int num; string name; public: Cstudent(string nam,int nnum) { name=nam; num=nnum; cout<<name<<" Constructor called.\n"; } void display() { cout<<"学号:"<<num<<endl; cout<<"姓名:"<<name<<endl; } ~Cstudent() { cout<<name<<" Destructor called\n"; } }; int main() { Cstudent stud1("zhangsan",1); Cstudent stud2("lisi",2); return 0; }
一般情况下,调用析构函数的次序与调用构造函数的次序相反。
(7)静态成员--静态数据成员
静态数据成员被类内所有的对象共享,某个对象对静态数据成员做出修改,则其他所有对象也共享被修改后的值。
静态数据成员的存储空间不会随着对象的产生而分配,也不会随着对象的消失而释放。
因此,静态数据成员不能在类体内初始化。
如果未对静态数据成员赋初值,默认为0;其他成员不会默认为0;
class Cstudent { private: string name; int score; static int studenttotal; static int sumscore; public: Cstudent(string nam,int scor) { name=nam; score=scor; studenttotal++; sumscore+=scor; cout<<name<<" Constructor called.\n"; } static float average(); ~Cstudent(); }; int Cstudent::studenttotal=0; int Cstudent::sumscore=0;
(8)静态成员--静态成员函数
一般情况下,静态成员函数只访问静态成员。也可以访问非静态成员,但要指明其所属对象,但这样麻烦,所以不用。
class Cstudent { private: string name; int score; static int studenttotal; static int sumscore; public: Cstudent(string nam,int scor) { name=nam; score=scor; studenttotal++; sumscore+=scor; cout<<name<<" Constructor called.\n"; } static float average();//******* ~Cstudent(); }; int Cstudent::studenttotal=0; int Cstudent::sumscore=0; float Cstudent::average() //********** { return (sumscore*1./studenttotal); }
静态成员的访问
一般是:类名::静态数据成员名
#include<iostream> #include<cstdio> using namespace std; class Cstudent { private: string name; int score; static int studenttotal; static int sumscore; public: Cstudent(string nam,int scor) { name=nam; score=scor; studenttotal++; sumscore+=scor; cout<<name<<" Constructor called.\n"; } static float average();//******* ~Cstudent(); }; int Cstudent::studenttotal=0; int Cstudent::sumscore=0; float Cstudent::average() //********** { return (sumscore*1./studenttotal); } Cstudent::~Cstudent() { studenttotal--; sumscore-=score; cout<<name<<" Destructor called.\n"; } int main() { Cstudent stud[2]={Cstudent("zhangsan",90),Cstudent("wangwu",100)}; cout<<Cstudent::average()<<endl; return 0; }
原文:https://www.cnblogs.com/zzyh/p/11914508.html