C++面向对象程序设计 谭浩强编著 授课教师:姬广永 QQ:41588872 学习网站:http://www.xin126.cn
面向对象程序设计 第二章 类和对象2
同类型的对象之间可以整体赋值,这种赋值与对象的成员的访问权限无关。 class A { float x,y; public: float m,n; void Setxy( float a, float b ){ x=a; y=b; } void Print(void) { cout<<x<<‘\t’<<y<<endl; } }; int main() { A a1,a2; a1.m=10; a1.n=20; //为公有成员数据赋值 a1.Setxy(2.0,5.0); a2=a1; a1.Print(); a2.Print(); } 同类型的对象之间可以整体赋值 相当于成员数据间相互赋值
成员函数与成员数据的定义不分先后,可以先说明函数原型,再在类体外定义函数体。 class A { float x, y; public: void Setxy(float a,float b) { x=a; y=b; } void Print(void) { cout<<x<<‘\t’<<y<<endl; } }; 在类体内定义成员函数
class A { float x, y; public: void Setxy(float a,float b); void Print(void); }; 在类体内说明成员函数原型 void A::Setxy(float a,float b) { x=a; y=b; } void A::Print(void) { cout<<x<<‘\t’<<y<<endl; } 在类体外定义成员函数
void A::Setxy(float a,float b) { x=a; y=b; } 在类体外定义成员函数的格式: <type> < class_name > :: < func_name > (<参数表>) { ...... //函数体 } 类名 函数类型 函数名 形参列表 void A::Setxy(float a,float b) { x=a; y=b; } 函数体
在C++语言中,结构体类型只是类的一个特例。结构体类型与类的唯一的区别在于:在类中,其成员的缺省的存取权限是私有的;而在结构体类型中,其成员的缺省的存取权限是公有的。
内联成员函数 当我们定义一个类时,可以在类中直接定义函数体。这时成员函数在编译时是作为内联函数来实现的。 同时,我们也可以在类体外定义类的内联成员函数,在类体内说明函数,在类体外定义时,在成员函数的定义前面加上关键字inline。 class A { float x, y; public: void Setxy(float a,float b); void Print(void); }; 说明该成员函数为内联 inline void A::Setxy(float a,float b) { x=a; y=b; } inline void A::Print(void) { cout<<x<<‘\t’<<y<<endl; }
类的嵌套 在定义一个类时, 在其类体中又包含了一个类的完整定义,称为类的嵌套 。 类是允许嵌套定义的 。
class A { class B{ int i,j; public : void Setij(int m, int n){ i=m; j=n; } }; float x,y; public: B b1,b2; void Setxy( float a, float b ){ x=a; y=b; } void Print(void) { cout<<x<<‘\t’<<y<<endl; } 类B包含在类A中,为嵌套定义 嵌套类的对象
类引用举例(三角形类:三角形的三边及与三边相关的运算) class Triangle{ private: float a,b,c; //三边为私有成员数据 public: void Setabc(float x, float y, float z);//置三边的值 void Getabc(float &x, float &y, float &z);//取三边的值 float Perimeter( );//计算三角形的周长 float Area( );//计算三角形的面积 void Print( );//打印相关信息 };
void Triangle::Setabc (float x,float y,float z) {a =x; b=y; c=z; } //置三边的值 void Triangle::Getabc (float &x,float &y,float &z) //取三边的值 {x=a; y=b; z=c;} float Triangle::Perimeter () {return (a+b+c);} //计算三角形的周长
float Triangle::Area () //计算三角形的面积 {float area,p; p= Perimeter()/2; area=sqrt((p-a)*(p-b)*(p-c)*p); return area; } void Triangle::Print(void) //打印相关信息 {cout<<"Peri="<<Perimeter()<<'\t'<<"Area="<<Area()<<endl;}
Tri1.Setabc (4,5,6); //为三边置初值 float x,y,z; void main(void) { Triangle Tri1; //定义三角形类的一个实例(对象) Tri1.Setabc (4,5,6); //为三边置初值 float x,y,z; Tri1.Getabc (x,y,z); //将三边的值为x,y,z赋值 cout<<x<<'\t'<<y<<'\t'<<z<<endl; cout<<"s="<<Tri1.Perimeter ()<<endl;//求三角形的周长 cout<<"Area="<<Tri1.Area ()<<endl; //求三角形的面积 Tri1.Print ();//打印有关信息 }
类引用举例(学生类:学生的姓名成绩及相关的运算) #include<iostream> #include<string> using namespace std; class Stu { string name; //学生姓名 float Chinese; //语文成绩 float Math; //数学成绩 public: float Average(void); //计算平均成绩 float Sum(void); //计算总分 void Show(void); //打印信息 void SetStudent(string,float,float); //为对象置姓名、成绩 void SetName(string name1)//为对象置姓名 { name=name1; } string GetName(){return name;} //取得学生姓名 };
{ return (Chinese+Math)/2;}//平均成绩 float Stu::Average( ) { return (Chinese+Math)/2;}//平均成绩 float Stu::Sum( ){ return Chinese+Math; }//总分 void Stu::Show( ) //打印信息 { cout<<"Name: "<<name<<endl<<"Score: "<<Chinese<<'\t'<< Math<<'\t'<<"average: "<<Average()<<'\t'<<"Sum: "<<Sum()<<endl;}
void Stu::SetStudent(string name1,float chinese,float math) { name=name1; //置姓名 Chinese=chinese; //置语文成绩 Math=math; //置数学成绩 }
void main( ) { Stu p1,p2; p1.SetStudent("Li qing",98,96);//对象置初值 p2.SetStudent("Wang Gang",90,88); //对象置初值 p1.Show();//打印信息 p2.Show();//打印信息 p1.SetName ("Zhao jian");//重新置p1对象的名字 p1.Show (); cout<<"p1.Name:"<<p1.GetName ()<<endl;//打印对象的名字 cout<<"p1.average:"<<p1.Average ()<<endl;//打印对象的成绩 }
成员函数的重载 类中的成员函数与前面介绍的普通函数一样,成员函数可以带有缺省的参数,也可以重载成员函数 。
class Test{ int x , y; int m, n; public: void Setxy(int a, int b){x=a; y=b;} void Setxy(int a,int b,int c,int d){ x=a;y=b;m=c;n=d;} void Printxy(int x){cout<< “m="<<m<<'\t'<<“n="<<n<<endl;} void Printxy( ) {cout<<"x="<<x<<'\t'<<"y="<<y<<endl;} } ; void main(void) { Test p1,p2; p1.Setxy(3, 5); p2.Setxy(10,20,30,40);//参数不同 p1.Printxy(); p2.Printxy(); p2.Printxy(2);//参数、类型不同 } 输出:x=3 y=5 x=10 y=20 m=30 n=40
可以有缺省参数的成员函数,若形参不完全缺省,则必须从形参的右边开始缺省。
缺省参数的成员函数 class A{ float x,y; public: float Sum(void) { return x+y; } void Set(float a,float b=10.0) { x=a; y=b;} void Print(void) { cout<<"x="<<x<<'\t'<<"y="<<y<<endl; } }; void main(void) { A a1,a2; a1.Set (2.0,4.0); cout<<"a1: "; a1.Print (); cout<<"a1.sum="<<a1.Sum ()<<endl; a2.Set(20.0); cout<<"a2: "; a2.Print (); cout<<"a2.sum="<<a2.Sum ()<<endl; } 不缺省参数,a1.x=2, a1.y=4 缺省参数,a2.x=20, a2.y=10
类声明和成员函数定义的分离 如果一个类只被一个程序使用,那么类的声明和成员函数的定义可直接写在的开头,但是一个类如果被多个程序使用,这样做的工作重复量就很大啦了,效率就太低啦!在面向对象的程序开发中一般做法是将类的声明(其中包括成员函数的声明)放在指定的头文件中,用户如果想用该类,只要把相关的头文件包含进来即可,不必在程序中重复书写类的声明,以减少工作量,节省篇幅,提高编程的效率!