本博文源于《C++面向对象程序设计陈维兴第三版》,第四章所有例题进行汇总!
文章目录
1.自引用指针this2. 对象数组与对象指针2.1 对象数组2.2 对象指针2.2.1 用对象指针访问单个对象成员2.2.2 用对象指针访问对象数组2.3 string类3. 向函数传递对象3.1 使用对象作为函数参数3.2 使用对象指针作为函数参数3.3 使用对象引用作为函数参数4. 静态成员4.1 静态数据成员4.2 静态成员函数5. 友元5.1 友元函数5.2 友元类6. 类的组合7. 共享数据的保护7.1 常引用7.2 常对象7.3 常对象成员8.C++程序的多文件组成程序举例本章小结1.自引用指针this
例4.1 显示this指针的值
#include<iostream>using namespace std;class Score{public:Score(int m,int f);void showScore();private:int mid_exam;int fin_exam;};Score::Score(int m,int f){mid_exam = m;fin_exam = f;}void Score::showScore() {cout << "this address:" << this << "final exam:" << this->fin_exam << endl;}int main(){Score score1(80,88);Score score2(80,88);Score score3(80,88);score1.showScore();score2.showScore();score3.showScore();return 0;}
例4.2 隐式this指针值
#include<iostream>using namespace std;class Score{public:Score(int m,int f);void showScore();private:int mid_exam;int fin_exam;};Score::Score(int m,int f){mid_exam = m;fin_exam = f;}void Score::showScore() {cout << "this address:" << this << "final exam:" << fin_exam << endl;}int main(){Score score1(80,88);Score score2(80,88);Score score3(80,88);score1.showScore();score2.showScore();score3.showScore();return 0;}
例子4.3 分析下列程序的运行结果
this指针是调用该成员函数的对象的地址,*this指针是调用该成员函数的对象。
#include<iostream>using namespace std;class Sample{public:Sample(int i =0,int j = 0){x = i;y = j;}void copy(Sample& xy);void print(){cout << x << "," << y << endl;}private:int x,y;};void Sample::copy(Sample& xy){if(this==&xy) {return ;}*this = xy;}int main(){Sample p1,p2(5,6);p1.copy(p1);p1.print();return 0;}
2. 对象数组与对象指针
2.1 对象数组
例子4.4 用只有一个参数的构造函数给对象数组赋值
#include<iostream>using namespace std;class exam{public:exam(int n){x= n;}int get_x(){return x;}private:int x;};int main(){exam obj1[4] = {11,22,33,44};for(int i= 0;i<4;i++)cout << obj1[i].get_x() << " ";cout << endl;return 0;}
例子4.5 用不带参数和带一个参数的构造函数给对象数组赋值
#include<iostream>using namespace std;class exam{public:exam(){x = 123;}exam(int n){x = n;}int get_x(){return x;}private:int x;};int main(){exam obj1[4] = {11,22,33,44};exam ob2[4] = {55,66};for(int i = 0;i<4;i++)cout << obj1[i].get_x() << " ";cout << endl;for(int i = 0;i<4;i++)cout << ob2[i].get_x() << " ";cout << endl;return 0;}
如果有多个参数,可以这样定义
Score rec[3] = {Score(80,80),Score(80,80),Score(80,80)};
例子4.6 用带有多个参数的构造函数给对象数组赋值
#include<iostream>using namespace std;class Score{public:Score(int m,int f);void showScore();private:int mid_exam;int fin_exam;};Score::Score(int m,int f){mid_exam = m;fin_exam = f;}void Score::showScore() {cout << mid_exam << "fin_exam" << fin_exam << endl;}int main(){Score rec[3] = {Score(80,88),Score(80,88),Score(80,88),};for(int i = 0;i<3;i++)rec[i].showScore();return 0;}
2.2 对象指针
2.2.1 用对象指针访问单个对象成员
4.7 对象指针的使用
#include<iostream>using namespace std;class Score{public:void setScore(int m,int f);void showScore();private:int mid_exam;int fin_exam;};void Score::setScore(int m,int f){mid_exam = m;fin_exam = f;}void Score::showScore() {cout << mid_exam << " fin_exam " << fin_exam << endl;}int main(){Score score;Score *pd;pd = &score;pd->setScore(80,88);pd->showScore();return 0;}
2.2.2 用对象指针访问对象数组
例子4.8 以相反的顺序显示对象数组的成员
#include<iostream>using namespace std;class Example{public:Example(int n,int m){x= n;y = m;}int get_x(){return x;}int get_y(){return y;}private:int x,y;};int main(){Example op[4] = {Example(1,2),Example(3,4),Example(5,6),Example(7,8),};int i;Example *p;p = &op[3];for(i=0;i<4;i++){cout << p->get_x() << " ";cout << p->get_y() << endl;p--;}cout << endl;return 0;}
2.3 string类
4.9 string类运算符的操作
#include<iostream>#include<string>using namespace std;int main(){string str1= "ABC";string str2= "DEF";string str3( "GHI");string str4, str5;str4= str1;cout << "str4 is " << str4 << endl;//字符串连接str5 = str1 + str2;cout << " str1 + str2 is" << str5 << endl;str5 = str1 + "123";cout << "str1 + \"123\" is "<< str5 << endl;//字符串比较if(str3>str1)cout << "str3>str1" << endl;else cout << "str3<str1" << endl;if(str4 == str1)cout << "str4==str1" << endl;elsecout << "str4<>stsr1" << endl;cout << "请输入一个字符串给str5";cin>> str5;cout << "str5 is " << str5 << endl;return 0;}
3. 向函数传递对象
3.1 使用对象作为函数参数
例子4.10 使用对象作为函数参数
#include<iostream>using namespace std;class aClass {public:aClass(int n){i = n;}void set(int n){i = n;}int get(){return i;}private:int i;};void sqr(aClass ob){ob.set(ob.get()*ob.get());cout << "sqr()function object:" ;cout << ob.get() << endl;}int main(){aClass obj(10);sqr(obj);cout << "main function objection is:";cout << obj.get();return 0;}
3.2 使用对象指针作为函数参数
例子4.11使用对象指针作为函数参数
#include<iostream>using namespace std;class aClass {public:aClass(int n){i = n;}void set(int n){i = n;}int get(){return i;}private:int i;};void sqr(aClass *ob){ob->set(ob->get()*ob->get());cout << "sqr()function object:" ;cout << ob->get() << endl;}int main(){aClass obj(10);sqr(&obj);cout << "main function objection is:";cout << obj.get();return 0;}
3.3 使用对象引用作为函数参数
4.12 适用对象引用作为函数参数
#include<iostream>using namespace std;class aClass {public:aClass(int n){i = n;}void set(int n){i = n;}int get(){return i;}private:int i;};void sqr(aClass &ob){ob.set(ob.get()*ob.get());cout << "sqr()function object:" ;cout << ob.get() << endl;}int main(){aClass obj(10);sqr(obj);cout << "main function objection is:";cout << obj.get();return 0;}
4. 静态成员
4.1 静态数据成员
4.13 静态数据成员计算两个学生期末成绩的总成绩和平均成绩
#include<iostream>using namespace std;class Score{public:Score(int m,int f);Score();~Score();void showScore();void show_count_sum_ave();private:int mid_exam;int fin_exam;static int count;static float sum;static float ave;};Score::Score(int m,int f){mid_exam = m;fin_exam = f;++ count;sum+=fin_exam;ave = sum/count;}Score::~Score(){}void Score::showScore(){cout << "mid_exam" << mid_exam << "fin_exam" << fin_exam << endl;}void Score::show_count_sum_ave(){cout << endl << "student number" << count;cout << endl << "final median score" << ave;cout << endl;}int Score::count=0.0;float Score::sum = 0.0;float Score::ave = 0.0;int main(){Score score1(80,88);score1.showScore();score1.show_count_sum_ave();Score score2(90,97);score2.show_count_sum_ave();return 0;}
例子4.14 使用静态数据成员计算3个学生期末成绩的总成绩和平均成绩,适用对象数组存储数据
#include<iostream>using namespace std;class Score{public:Score(int m,int f);~Score();void show_count_sum_ave();private:int mid_exam;int fin_exam;static int count;static float sum;static float ave;};Score::Score(int m,int f){mid_exam = m;fin_exam = f;++ count;sum+=fin_exam;ave = sum/count;}Score::~Score(){}void Score::show_count_sum_ave(){cout << endl << "student number" << count;cout << endl << "final median score" << ave;cout << endl;}int Score::count=0.0;float Score::sum = 0.0;float Score::ave = 0.0;int main(){Score rec[3] = {Score(80,88),Score(90,92),Score(70,80)};rec[3].show_count_sum_ave();return 0;}
例子4.15 公有静态数据成员的访问
#include<iostream>using namespace std;class myclass {public:static int i;};int myclass::i = 0;int main(){myclass::i = 200;myclass ob1,*p;p = &ob1;cout << "ob1.i: " << ob1.i << endl;cout << "myclass::i:" << myclass::i<< endl;cout << "p->i:" << p->i << endl;return 0;}
4.2 静态成员函数
例子4.16 静态成员函数访问静态数据成员
#include<iostream>using namespace std;class Score{public:Score(int m,int f);~Score();static void show_count_sum_ave();private:int mid_exam;int fin_exam;static int count;static float sum;static float ave;};Score::Score(int m,int f){mid_exam = m;fin_exam = f;++ count;sum+=fin_exam;ave = sum/count;}Score::~Score(){}int Score::count=0.0;float Score::sum = 0.0;float Score::ave = 0.0;void Score::show_count_sum_ave(){cout << endl << "student number" << count;cout << endl << "final median score" << ave;cout << endl;}int main(){Score rec[3] = {Score(80,88),Score(90,92),Score(70,80)};rec[3].show_count_sum_ave();Score::show_count_sum_ave();return 0;}
一般而言,静态成员函数不访问类中的非静态成员。如确实需要,静态成员汗水只能通过对象名(或对象指针、对象引用)访问该对象的非静态成员
例子4.17 静态成员函数访问非静态数据成员
#include<iostream>using namespace std;class Score{public:Score(int m,int f);static void display(Score &s){cout << "the final exam:" << s.fin_exam << endl;}static void show_count_sum_ave();private:int mid_exam;int fin_exam;static int count;static float sum;static float ave;};Score::Score(int m,int f){mid_exam = m;fin_exam = f;++ count;sum+=fin_exam;ave = sum/count;}int Score::count=0.0;float Score::sum = 0.0;float Score::ave = 0.0;void Score::show_count_sum_ave(){cout << endl << "student number" << count;cout << endl << "final median score" << ave;cout << endl;}int main(){Score rec[3] = {Score(80,88),Score(90,92),Score(70,80)};Score::display(rec[0]);Score::display(rec[1]);Score::display(rec[2]);Score::show_count_sum_ave();return 0;}
5. 友元
5.1 友元函数
4.18 将非常元函数声明为友元函数
#include<iostream>using namespace std;class Score{public:Score(int m,int f);void showScore();friend int Score_get(Score &);private:int mid_exam;int fin_exam;};Score::Score(int m,int f){mid_exam = m;fin_exam = f;}int Score_get(Score &ob){return (int)(0.3*ob.mid_exam+0.7*ob.fin_exam);}int main(){Score rec[3] = {Score(80,88),Score(90,92),Score(70,80)};cout << "san ge" << endl;for(int i =0;i<3;i++)cout << Score_get(rec[i]) << endl;return 0;}
例4.19 一个函数同时定义为两个类的友元函数
#include<iostream>using namespace std;class Student;class Score{public:Score(int m,int f):mid_exam(m),fin_exam(f){};friend void showScore_Student(Score &sc,Student& st);private:int mid_exam;int fin_exam;};class Student{public:Student(string na,int num){name = na;number = num;}friend void showScore_Student(Score& sc,Student& st);private:string name;int number;};void showScore_Student(Score& sc,Student& st){cout << "name:" << st.name << endl << "number:" << st.number << endl;cout << "mid_exam" << sc.mid_exam << endl << "number:" << sc.fin_exam << endl;}int main(){Score score1(90,92);Student stu1("DianaLin",80204);showScore_Student(score1,stu1);return 0;}
2. 将成员函数声明为友元函数
例子4.20 一个类的成员函数作为另一个类的友元
#include<iostream>using namespace std;class Score;class Student{public:Student(string na,int num){name = na;number = num;}void showScore_Student(Score& sc);private:string name;int number;};class Score{public:Score(int m,int f):mid_exam(m),fin_exam(f){};friend void Student::showScore_Student(Score &sc);private:int mid_exam;int fin_exam;};void Student::showScore_Student(Score &sc){cout << "name:" << name << endl << "number:" << number << endl;cout << "mid_exam:" << sc.mid_exam << "final_exam" << sc.fin_exam << endl;}int main(){Score score1(90,92);Student stu1("DianaLin",80204);stu1.showScore_Student(score1);return 0;}
5.2 友元类
例子4.211 一个类作为另一个类的友元
#include<iostream>using namespace std;class Score;class Student{public:Student(string na,int num){name = na;number = num;}void showScore_Student(Score& sc);private:string name;int number;};class Score{public:Score(int m,int f):mid_exam(m),fin_exam(f){};friend Student;private:int mid_exam;int fin_exam;};void Student::showScore_Student(Score &sc){cout << "name:" << name << endl << "number:" << number << endl;cout << "mid_exam:" << sc.mid_exam << "final_exam" << sc.fin_exam << endl;}int main(){Score score1(90,92);Student stu1("DianaLin",80204);stu1.showScore_Student(score1);return 0;}
6. 类的组合
例子4.22 对象成员的初始化
#include<iostream>using namespace std;class X{public:X(int a1,double b1){a= a1;b = b1;}void disp(){cout << "a=" << a << endl;cout << "b= " << b << endl;}private:int a;double b;};class Y {public:Y(int a1,double b1,int c1):xx(a1,b1){c= c1;}void disp(){xx.disp();cout << "c=" << c << endl;}private:X xx;int c;};int main(){Y b(123,456,789);b.disp();return 0;}
例子4.23 学生类中嵌套着一个日期类对象,要求显示学生的姓名和出生日期
#include<iostream>#include<string>using namespace std;class Date{public:Date(int y,int m,int d);void showDate();private:int year;int month;int day;};Date::Date(int y,int m,int d){year = y;month = m;day = d;}void Date::showDate() {cout << year << "." << month << "." << day << endl;}class Student{public:Student(string name1,int y1,int m1,int d1);void show();private:string name;Date birthday;};Student::Student(string name1,int y1,int m1,int d1): birthday(y1,m1,d1){name = name1;}void Student::show(){cout << "name:" << name << endl;cout << "birthdate: ";birthday.showDate();}int main(){Student stu1("liming",1998,7,2);stu1.show();return 0;}
7. 共享数据的保护
7.1 常引用
例子4.24 常引用做函数形参
#include<iostream>using namespace std;int add(const int&,const int&);int main(){int a = 20;int b = 30;cout << a << "+" << b << "=" << add(a,b) << endl;return 0 ;}int add(const int &i,const int& j){return i+j;}
7.2 常对象
例子4.25 非常对常对象的比较
#include<iostream>#include<string>using namespace std;class Date{public:Date(int y,int m,int d);void setDate(int y,int m,int d);void showDate();private:int year;int month;int day;};Date::Date(int y,int m,int d){year = y;month = m;day = d;}void Date::setDate(int y,int m,int d){year = y;month = m;day = d;}void Date::showDate() {cout << year << "." << month << "." << day << endl;}int main(){Date date1(,4,28);date1.showDate();date1.setDate(,121,15);date1.showDate();return 0;}
7.3 常对象成员
例子常数据成员举例
#include<iostream>#include<string>using namespace std;class Date{public:Date(int y,int m,int d);void showDate();private:const int year;const int month;const int day;};Date::Date(int y,int m,int d):year(y),month(m),day(d){}void Date::showDate() {cout << year << "." << month << "." << day << endl;}int main(){Date date1(,4,28);date1.showDate();return 0;}
如果在一个类中说明了常数据成员,那么构造函数就只能通过初始化列表对该数据成员进行初始化,而任何其他函数都不能对成员赋值。
例子4.27 常成员函数的使用
#include<iostream>#include<string>using namespace std;class Date{public:Date(int y,int m,int d);void showDate();void showDate() const ;private:const int year;const int month;const int day;};Date::Date(int y,int m,int d):year(y),month(m),day(d){}void Date::showDate() {cout << "common showDate:" << endl;cout << year << "." << month << "." << day << endl;}void Date::showDate() const {cout << "const showDate:" << endl;cout << year << "." << month << "." << day << endl;}int main(){Date date1(,4,28);date1.showDate();const Date date2(,11,14);date2.showDate();return 0;}
常成员函数可以访问常数据成员,也可以访问普通数据成员。常数据成员可以被常成员函数访问,也可以被普通成员函数访问如果将一个对象说明说明为常对象,则通过该对象只能调用它的常成员函数,而不能调用普通成员函数,常成员函数是常对象唯一的对外接口,这是C++语法机制上对常对象的保护常成员函数不能更新对象的数据成员,也不能调用该类的普通成员函数1,这就保证了在常成员函数中绝对不会更新数据成员的值。
8.C++程序的多文件组成
整篇小节主要阐述了,将一个CPP文件分为若干个文件,其中包括
student.h(类声明文件)student.cpp(类实现文件)studentmain.cpp(类使用文件)
程序举例
下面就以类模拟堆栈进行举例。
创建Stack.h
//// Created by Administrator on /12/25/025.//#include<iostream>const int SIZE = 10;class Stack{private:int stck[SIZE];int tos;public:Stack();void push(int ch);int pop();void ShowStack();};
创建Stack.cpp
//// Created by Administrator on /12/25/025.//#include"Stack.h"Stack::Stack(){tos = 0;//初始化栈顶}void Stack::push(int ch){if(tos == SIZE){std::cout << "Stack is full";return ;}stck[tos] = ch;tos ++ ;std::cout <<"You have pushed a data into the stack!\n";}int Stack::pop(){if(tos == 0){std::cout << "Stack is empty";return 0;}tos--;return stck[tos];}void Stack::ShowStack(){std::cout << "The content of stack: \n";if(tos == 0){std::cout << "The stack has no data!\n";return ;}for(int i = tos-1;i>=0;i--)std::cout << stck[i] << " ";std::cout << std::endl;}
创建StackMain.cpp
//// Created by Administrator on /12/25/025.//#include<iostream>#include"Stack.h"using namespace std;int main(){Stack ss;int x;char ch;cout << "<I> -----Push data to stack" << endl;cout << "<O> -----Pop data from stack" << endl;cout << "<S> -----Show the content of stack" << endl;cout << "<Q> -----Quit...." << endl;while(1){cout << "Please select an item: ";cin >> ch;ch = toupper(ch);switch (ch) {case 'I':cout << "Enter the value that" << "You want to push:";cin >> x;ss.push(x);break;case 'O':x = ss.pop();cout << "Pop" << x << "from stack.\n";break;case 'S':ss.ShowStack();break;case 'Q':return 0;default:cout << "You have inputted a wrong item Please try again!" << endl;continue;}}}