面向对象知识点
-
构造函数无返回类型,与类名同名;
复制构造函数用于创建对象、形实参结合、返回和接收对象; -
公有继承(public):基类的公有成员和保护成员在派生类中仍是公有成员和保护成员。
私有继承(private):基类的公有成员和保护成员都作为派生类的私有成员。
保护继承(protected):基类的所有公有成员和保护成员都成为派生类的保护成员。 -
友元类和友元函数:可在类外面访问类的私有成员等。
友元类的所有成员函数都是另一个类的友元函数,友元函数是可以直接访问类的私有成员的非成员函数; -
类的静态成员变量:统计类对象个数。
类的静态成员函数:直接调用静态成员变量。 -
包含纯虚函数的类是抽象类,抽象类可以派生子类,但是不能创建对象,可以声明类变量;
-
构造函数的默认形参值定义时:从右向左定义;调用时:从左向右匹配;
-
函数重载的条件:形参个数、形参类型和const;
-
静态联编:指在程序编译阶段完成联编过程。
动态联编:指在程序运行阶段完成联编过程。 -
虚函数:基类中说明了虚函数后,派生类中与其对应的函数可不必说明为虚函数。
-
友元机制:破坏类的封装与隐藏。
引入友元机制的主要作用:可以实现在类的外部访问类的私有成员。 -
C++语言中不能重载的运算符:
成员访问运算符(“.”),成员指针访问运算符(“.*”),作用域分辨符(“::”),计算数据大小运算符(“sizeof”),三目运算符(“?:”)。 -
C++语言中的多态:动态多态和静态多态
-
重载为类的非成员函数:<参数表>中的参数个数一般与运算符原操作数的个数相同。
重载为类的成员函数:<参数表>中的参数个数一般是运算符原操作数的个数减1。 -
书上的Clock程序:
成员变量:HMS;
构造函数,settime,showtime,计时++,创建对象,调用函数。定义一个描述时钟的类MyClock,数据成员包括时钟的时、分、秒(int hour;int minute;int second;),给该时钟类增加合适的成员函数。#include <iostream> using namespace std; class MyClock { private: int hour, minute, second; public: MyClock(int H, int M, int S) { hour = H; minute = M; second = S; } void SetTime(int H, int M, int S) { hour = H; minute = M; second = S; } void ShowTime() { printf("%02d:%02d:%02d\n", hour, minute, second); } MyClock &operator++() { // 前置 ++ second ++; if(second >= 60) second -= 60, minute ++; if(minute >= 60) minute -= 60, hour ++; if(hour >= 24) hour -= 24; return *this; } MyClock operator++(int) { // 后置 ++ MyClock old = *this; ++ (*this); return old; } friend ostream& operator << (ostream& os, MyClock M); // 友元重载 <<输出 }; ostream& operator << (ostream& os, MyClock M) { os << M.hour << ":" << M.minute << ":" << M.second; return os; } int main() { MyClock MC(23, 59, 59); MC.ShowTime(); (++ MC).ShowTime(); (MC ++).ShowTime(); cout << MC << endl; // 使用 <<重载 return 0; }
-
学生类:
成员变量:学号,姓名,学生个数统计count静态变量;
函数:构造函数,复制构造函数,统计count的静态函数:创建对象,调用函数。#include <iostream> #include <string> using namespace std; class stu { private: int sid; string sname; public: static int countS; stu(int id, string name) { sid = id; sname = name; countS ++; } stu(stu &s) { sid = s.sid; sname = s.sname; countS ++; } ~stu() { countS --; } static int GetCount() { return countS; } }; int stu::countS = 0; int main() { stu s1(219074193, "ZZY"); cout << stu::GetCount() << endl; stu s2(s1); cout << s2.GetCount() << endl; return 0; }
-
学生类:
成员变量:学号,姓名char[],年龄,计算机、网络等多门课成绩。
成员函数:构造函数,复制构造函数,使用友元函数统计3个学生的均分。#include <iostream> #include <cstring> using namespace std; class student { private: int sid, sage; char sname[20]; double s1, s2, s3; public: student(int id, char name[], int age, double S1, double S2, double S3) { sid = id, sage = age; strcpy(sname, name); s1 = S1, s2 = S2, s3 = S3; } student(student &a) { sid = a.sid, sage = a.sage; strcpy(sname, a.sname); s1 = a.s1, s2 = a.s2, s3 = a.s3; } double getAve() { return (s1+s2+s3)/3.0; } friend double getStuAvg(student &a1, student &a2, student &a3); }; double getStuAvg(student &a1, student &a2, student &a3) { return (a1.getAve() + a2.getAve() + a3.getAve()) / 3.0; } int main() { student stu1(219074193, "ZZY", 20, 97, 90, 92); student stu2(219074194, "CWC", 19, 90, 87, 95); student stu3(219074195, "DDC", 20, 99, 99, 99); cout << getStuAvg(stu1, stu2, stu3) << endl; return 0; }
-
Father类派生son类:
成员函数:构造函数和复制构造函数和析构函数并输出字符串,运行测试。#include <iostream> using namespace std; class Father { public: Father() { cout << "Father构造函数已经执行" << endl; } Father(Father &F) { cout << "Father复制构造函数已经执行" << endl; } ~Father() { cout << "Father析构函数已经执行" << endl; } }; class Son:public Father { public: Son() { cout << "Son构造函数已经执行" << endl; } Son(Son &S) { cout << "Son复制构造函数已经执行" << endl; } ~Son() { cout << "Son析构函数已经执行" << endl; } }; class Grandson:public Son { public: Grandson() { cout << "Grandson构造函数已经执行" << endl; } Grandson(Grandson &GS) { cout << "Grandson复制构造函数已经执行" << endl; } ~Grandson() { cout << "Grandson析构函数已经执行" << endl; } }; int main() { Father F; Son S; Grandson GS; return 0; }
-
定义一个点类与矩形类(组合类),其中矩形类的成员Point p0表示其左上角坐标,注意构造函数。
#include <iostream> using namespace std; class Point { private: double x, y; public: Point(int a, int b) { x = a; y = b; } Point(Point &p) { x = p.x; y = p.y; } void PS() { cout << x << " " << y << endl; } }; class Rect { private: Point p0; double l, r; public: Rect(Point p, double a, double b):p0(p) { l = a; r = b; } void RS() { p0.PS(); cout << l << " " << r << endl; } }; int main() { Point p(2.2, 3.3); Rect r(p, 5.5, 9.2); r.RS(); return 0; }
-
编写一个抽象类Shape,在此基础之上派生出类Rectangle(矩形类)和Circle(圆类),二者都有计算面积的函数getArea()和周长的函数getPerim()。
#include <iostream> using namespace std; const double PI = 3.14; class shape { public: shape() { } ~shape() { } virtual double GetArea() = 0; virtual double GetPerim() = 0; }; class Rect:public shape { private: double l, w; public: Rect(double a, double b) { l = a; w = b; } ~Rect() { } double GetArea() { return l*w; } double GetPerim() { return 2.0*(l+w); } }; class Cir:public shape { private: double r; public: Cir(double a) { r = a; } ~Cir() { } double GetArea() { return r*r*PI; } double GetPerim() { return 2*PI*r; } }; int main() { Rect r(2.5, 3.5); Cir c(3.5); cout << r.GetArea() << endl; cout << r.GetPerim() << endl; cout << c.GetArea() << endl; cout << c.GetPerim() << endl; return 0; }
-
分别定义一组重载函数,计算两个整数、浮点数(float或double) 复数之和。
#include <iostream> using namespace std; template<typename T> T MyAdd(T a, T b) { return a + b; } class Complex { private: double r, i; public: Complex(double a, double b) { r = a; i = b; } Complex operator + (const Complex &c) { Complex temp = *this; temp.r += c.r; temp.i += c.i; return temp; } void GetNum() { cout<<"("<<r<<", "<<i<<")"<<endl; } }; int main() { int a1 = 1, b1 = 2; cout << MyAdd(a1, b1) << endl; double a2 = 1.4, b2 = 2.7; cout << MyAdd(a2, b2) << endl; Complex a3(1.2, 2.2); Complex b3(2.1, 4.1); Complex ans3 = a3 + b3; ans3.GetNum(); return 0; }
-
港口集团对员工月工资:工资+奖金+小时工资*工作量。
处长工资+奖金=10K+20K;科长工资+奖金=5k+5K;科员工资+奖金=5k+1k。
定义员工抽象类,派生其他类,编写程序求收入。
virtual double 计算工资()=0;纯虚函数
姓名[20];specialty[20];//专业技能;年龄;工资;小时工资;工作量;职称;奖金;
构造函数、计算工资函数。main测试。#include <iostream> using namespace std; const double Czs=10000, Czj=20000, Kzs=5000, Kzj=5000, Kys=5000, Kyj=1000; class Staff { private: string name, special; int age; double timesales, works; public: Staff(string N,int A,double TS,double W,string S):name(N),age(A),timesales(TS),works(W),special(S) { } virtual double pay() = 0; double worksale() { return timesales*works; } }; class Cz:public Staff { public: Cz(string N,int A,double TS,double W,string S):Staff(N,A,TS,W,S) { } double pay() { return Czs + Czj + worksale(); } }; class Kz:public Staff { public: Kz(string N,int A,double TS,double W,string S):Staff(N,A,TS,W,S) { } double pay() { return Kzs + Kzj + worksale(); } }; class Ky:public Staff { public: Ky(string N,int A,double TS,double W,string S):Staff(N,A,TS,W,S) { } double pay() { return Kys + Kyj + worksale(); } }; int main() { Cz a("ZZY", 20, 5000, 80, "game1"); Kz b("TCC", 21, 4500, 80, "game2"); Ky c("DDC", 20, 4000, 80, "game3"); cout << a.pay() << " " << b.pay() << " " << c.pay(); return 0; }
-
虚基类:A,A派生B1、和B2,B1和B2派生出
A:ID、name;构造函数等;B1:职称,部门、构造函数等;B2:B21,B22,构造函数;C:职务级,专业技能、构造函数等;#include <iostream> #include <string> using namespace std; class A { private: int id; string name; public: A(int ID, string N) { id = ID; name = N; } }; class B1:virtual public A { private: string B11, B12; public: B1(int ID, string N, string KB11, string KB12):A(ID,N) { B11 = KB11; B12 = KB12; } }; class B2:virtual public A { private: string B21, B22; public: B2(int ID, string N, string KB21, string KB22):A(ID,N) { B21 = KB21; B22 = KB22; } }; class C:public B1,public B2 { private: int lev; string jn; public: C(int ID,string N,string KB11,string KB12,string KB21,string KB22,int L,string J):A(ID,N),B1(ID,N,KB11,KB12),B2(ID,N,KB21,KB22) { lev = L; jn = J; } }; int main() { C ZY(1001,"ZZY","KB11","KB12","KB21","KB22",5,"game"); return 0; }
-
某小型公司,主要有三类员工(Employee):
行政人员(AdminStaff)、兼职销售员(Salesman)、经理(Manager)。
行政人员拿固定月薪5000元(静态浮点型常量FS),兼职销售员按该销售员当月销售额的4%提成;
经理既是行政人员,也做销售工作,因此其月薪是固定月薪+销售提成。
运用虚基类+虚函数相关知识,设计抽象类Employee,包含姓名name数据成员(允许用string类)和计算月薪函数float pay();
然后派生出AdminStaff,增加固定月薪fixedSalary数据成员,实现其pay函数;
派生出Salesman,增加当月销售额sales数据成员,实现其pay函数;
再共同派生出Manager,实现其pay函数。在main中为每个派生类各创建一个对象;
放入Employee类型的指针数组;在for循环中统一处理不同派生类的对象,依次显示每位员工的姓名和工资,并汇总工资总额。#include <iostream> #include <string> using namespace std; static const float FS = 5000; class Employee { protected: string name; public: Employee(string Name = "") { name = Name; } virtual float pay() = 0; string getName() { return name; } }; class AdminStaff: virtual public Employee { protected: float fixedSalary; public: AdminStaff(string Name, float FixedSalary=FS):Employee(Name) { fixedSalary = FixedSalary; } float pay() { return fixedSalary; } }; class Salesman:virtual public Employee { protected: float sales; public: Salesman(string Name, float Sales=0):Employee(Name) { sales = Sales; } float pay() { return sales*0.04; } }; class Manager:public AdminStaff,public Salesman { public: Manager(string Name="", float FixedSalary=FS, float Sales=0):AdminStaff(Name, FixedSalary), Salesman(Name, Sales), Employee(Name) { } float pay() { return fixedSalary+sales*0.04; } }; int main() { AdminStaff as1("行政老张", FS); Salesman s1("销售小李", 200000); Manager m1("经理老王", FS, 100000); Employee *emp[3] = {&as1, &s1, &m1}; // 用指针数组的各元素存放各对象的地址 float sum = 0; for(int i = 0; i < 3; i ++) { cout << emp[i]->getName() << ",月薪" << emp[i]->pay() << endl; sum += emp[i]->pay(); } cout << "汇总:" << sum << endl; return 0; }