《C++面向对象程序设计导论》-从抽象到编程 课件 03 关联与连接_第1页
《C++面向对象程序设计导论》-从抽象到编程 课件 03 关联与连接_第2页
《C++面向对象程序设计导论》-从抽象到编程 课件 03 关联与连接_第3页
《C++面向对象程序设计导论》-从抽象到编程 课件 03 关联与连接_第4页
《C++面向对象程序设计导论》-从抽象到编程 课件 03 关联与连接_第5页
已阅读5页,还剩55页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

关联和连接及其实现《C++面向对象程序设计导论》--从抽象到编程第3章关联与连接3.1关联与连接的概念3.2关联的实现第3章关联与连接本节学习目标能够运用语文知识和数学知识解释关联和连接及其表述能够运用关联和连接描述事物之间的关系能够使用指针实现关联及其连接能够运用集合论解释关联和连接的实现方法连接(Link)是对客观事物之间的一个关系的抽象,是一个关系在计算机世界中的反映关联(Association)是对连接的抽象,是一种关系在计算机世界中的反映。关联和连接是面向对象思想中的两个基本概念3.1关联与连接的概念语文中,使用陈述语句描述客观事物及其相互关系,陈述语句主要采用“主动宾”格式数学中,使用元素之间的对应关系来描述客观事物及其相互关系3.1关联与连接的概念(表示)3.2.1使用指针实现多对一关联3.2.2使用指针数组实现多对多关联数学中,对应关系有一对一、多对一和多对多三种类型3.2关联的实现导航(Navigation)角色(Role)重数(Multiplicity)一个人喜欢一种体育运动一种体育运动可被多个人喜欢使用工具有助于发现解决问题的关键因素3.2.1使用指针实现多对一关联使用指针Sport*sport实现多对一关联like编码实现#include

"Sport.h"class

Person{public: Person(); Person(char*pName); ~Person();

boollike(Sport*likeSport); Sport*likedSport();

voidprint();

private:

charname[20];

Sport*sport;//指向最喜欢的运动};【例3.1】使用成员指针表示多对一关联中的连接class

Sport{public: Sport(); Sport(char*pName);

voidprint(); ~Sport();

private:

charname[20];};#include

<iostream>#include

<string.h>#include

"Sport.h"using

namespacestd;

Sport::Sport(){}Sport::Sport(char*pName){ strncpy(name,pName,sizeof(name)); name[sizeof(name)-1]='\0';}void

Sport::print(){ cout<<name<<endl;}Sport::~Sport(){}【例3.1】使用成员指针表示多对一关联中的连接#include

<iostream>#include

<string.h>#include

"Sport.h"#include

"Person.h"using

namespacestd;

Person::Person(){}Person::Person(char*pName){ strncpy(name,pName,sizeof(name)); name[sizeof(name)-1]='\0';}Person::~Person(){}voidPerson::like(Sport*likeSport){ sport=likeSport;}Sport*Person::likedSport(){

returnsport;}voidPerson::print(){ cout<<name;}#include<iostream>#include"Sport.h"#include"Person.h"usingnamespacestd;

voidmain(){ Sports1("足球"); Sports2("篮球"); Sports3("乒乓球");

Personp1("张三"); p1.like(&s1); p1.print(); cout<<"最喜欢"; p1.likedSport()->print();

Personp2("李四"); p2.like(&s2); p2.print(); cout<<"最喜欢"; p2.likedSport()->print();

Personp3("王五"); p3.like(&s2); p3.print(); cout<<"最喜欢"; p3.likedSport()->print();}【例3.2】维护多对一关联中的连接#include<iostream>#include<string.h>#include"Sport.h"#include"Person.h"usingnamespacestd;

Person::Person(){}Person::Person(char*pName){ strncpy(name,pName,sizeof(name)); name[sizeof(name)-1]='\0';}Person::~Person(){}voidPerson::like(Sport*likeSport){ sport=likeSport;}Sport*Person::likedSport(){ returnsport;}voidPerson::print(){ cout<<name;}#include<iostream>#include"Sport.h"#include"Person.h"usingnamespacestd;

voidmain(){ Sports1("足球"); Sports2("篮球"); Sports3("乒乓球");

Personp1("张三"); p1.like(&s1); p1.print();

cout<<"最喜欢"; p1.likedSport()->print();

Personp2("李四"); p2.like(&s2); p2.print(); cout<<"最喜欢"; p2.likedSport()->print();

Personp3("王五"); p3.like(&s2); p3.print(); cout<<"最喜欢"; p3.likedSport()->print();}【例3.2】维护多对一关联中的连接#include<iostream>#include"Sport.h"#include"Person.h"usingnamespacestd;voidmain(){ Sports1("足球"); Sports2("篮球"); Sports3("乒乓球");

Personp1("张三"); p1.like(&s1); p1.print(); cout<<"最喜欢"; p1.likedSport()->print();

Personp2("李四"); p2.like(&s2); p2.print(); cout<<"最喜欢"; p2.likedSport()->print();

Personp3("王五"); p3.like(&s2); p3.print(); cout<<"最喜欢"; p3.likedSport()->print();}【例3.2】维护多对一关联中的连接//Person.h#include

"Sport.h"class

Person{public: Person(); Person(char*pName); ~Person();

voidlike(Sport*likeSport); Sport**likedSport();

voidprint();

private:

charname[20];

Sport*sport[3];//指向喜欢的3项运动};3.2.2使用指针数组实现多对多关联一个人喜欢0到3种体育运动//Person.cpp#include<iostream>#include<string.h>#include"Sport.h"#include"Person.h"usingnamespacestd;

Person::Person(){ for(inti=0;i<3;i++) sport[i]=NULL;//设置为空,表示没有指向对象}Person::Person(char*pName){ strncpy(name,pName,sizeof(name)); name[sizeof(name)-1]='\0'; for(inti=0;i<3;i++) sport[i]=NULL;}Person::~Person(){}boolPerson::like(Sport*likeSport){ inti=0; while(i<3&&sport[i]) i++; if(i<3){ sport[i]=likeSport; returntrue; }else{ returnfalse;//超过3项返回错误 }}Sport**Person::likedSport(){ returnsport;}voidPerson::print(){ cout<<name; cout<<"喜欢"; for(inti=0;i<3;i++) sport[i]->print();}//app.cpp#include"Sport.h"#include"Person.h"usingnamespacestd;voidmain(){ Sports1("足球"); Sports2("篮球"); Sports3("乒乓球"); Sports4("跳高");

Personp1("张三"); p1.like(&s1); p1.like(&s2); p1.like(&s3); p1.like(&s4);//超过3项不存储 p1.print();

Personp2("李四"); p2.like(&s4); p2.like(&s3); p2.like(&s2); p2.like(&s1);//超过3项不存储 p2.print();}【例3.4】维护多对多关联中的连接张三喜欢足球篮球乒乓球李四喜欢跳高乒乓球篮球请使用时序图描述程序运行过程。例3.4程序的输出结果练习调试通过例3.4的代码按照下面的语义重做分析设计和编码实现一个人喜欢0到5种体育运动总结及进一步学习分析:使用关联和连接抽象事物之间的关系设计:使用关联、连接等UML工具描述类及对象之间的关系编码:使用指针编程实现关联及其连接3.3组合与聚合关联进一步学习第3章关联与连接3.3组合与聚合关联3.2关联的实现第3章关联与连接学习目标能够运用组合关联和聚合关联等知识解释事物的内部构成能够使用组合关联、聚合关联等UML工具描述事物的内部关系能够使用对象和指针实现组合关联能够使用代码实现聚合关联关联分为一般关联(Association)、聚合(Aggregation)和组合(Composition)三种3.3组合与聚合关联组合关联:具有相同的生命周期聚合关联:具有不同的生命周期3.3组合与聚合关联3.3.1使用对象实现组合关联3.3.2使用指针实现组合关联3.3.3使用代码实现聚合关联使用对象StudentIDstudentID实现组合关联3.3.1使用对象实现组合关联3.3.1使用对象实现组合关联//Student.h#include

"StudentID.h"

class

Student{public:Student();Student(intid);Student(intid,char*pName);Student(intid,char*pName,intxHours,floatxgpa);~Student();

private:

charname[20];intsemesHours;floatgpa;

StudentIDstudentID;//表示多对一组合关联中的连接};【例3.5】使用对象表示多对一组合关联的连接//StudentID.hclass

StudentID{public: StudentID(); StudentID(intid); ~StudentID();

voidprint();

private:

boolisValid(void);

intvalue;};//StudentID.cpp#include

<iostream>#include

<string.h>#include

"StudentID.h"using

namespacestd;

StudentID::StudentID(){ cout<<"\t"<<"调用构造函数StudentID()"<<endl;}StudentID::StudentID(int

id){ cout<<"\t"<<"调用构造函数StudentID("<<id<<")"<<endl;

if(isValid()) value=id;}StudentID::~StudentID(){ cout<<"析构StudentID:"<<value<<endl;}void

StudentID::print(){ cout<<value<<endl;}bool

StudentID::isValid(){

//可增加判断学号是否符合编码规则的代码

return

true;}

【例3.5】使用对象表示多对一组合关联的连接//Student.cpp#include

<iostream>#include

<string.h>#include

"StudentID.h"#include

"Student.h"using

namespacestd;

Student::Student(){ cout<<"调用构造函数Student()"<<endl<<endl;}

Student::Student(int

id):studentID(id)//增加了新的语法{ cout<<"调用构造函数Student("<<id<<")"<<endl<<endl;}

Student::Student(int

id,char*pName):studentID(id){ cout<<"调用构造函数Student("<<id<<","<<pName <<")"<<endl<<endl;

strncpy(name,pName,sizeof(name)); name[sizeof(name)-1]='\0';}

Student::Student(int

id,char*pName,int

xHours,float

xgpa):studentID(id){ cout<<"调用构造函数Student("<<id<<","<<pName <<","<<xHours<<","<<xgpa <<")"<<endl<<endl; strncpy(name,pName,sizeof(name)); name[sizeof(name)-1]='\0'; semesHours=xHours; gpa=xgpa;}

Student::~Student(){ cout<<"析构Student:"; studentID.print();}//app.cpp#include

"StudentID.h"#include

"Student.h"

voidmain(){ Students1(210101,"Randy"); Students2(210102,"Randy"); Students3(210103,"Jenny",10,3.5);}运行过程和结果3.3.2使用指针实现组合关联编写代码同步生命周期Person对象管理Tdate对象构造函数析构函数【例3.7】使用指针实现组合关联#include

<iostream>#include

"Tdate.h"#include

<iostream>using

namespacestd;class

Person{public: Person(){};

Person(char

n[],Tdated){ strncpy(name,n,sizeof(name)); name[sizeof(name)-1]='\0';

birthday=newTdate(d);//创建一个新的Tdate对象 };

~Person(){

deletebirthday;//删除连接的Tdate对象 };

voidprint(){ cout<<"Person:"<<name<<","; birthday->print(); }; TdategetBirthday()const{

returnTdate(*birthday);//返回一个新对象而没有返回指针birthday,以保证安全 }

Person(const

Person&oldPerson){ memcpy(this,&oldPerson,sizeof(Person));//将oldPerson的内存中的数据复制内存

birthday=newTdate(oldPerson.getBirthday());//创建一个新的Tdate对象 };private:

Tdate*birthday;//使用指针表示多对一组合关联

charname[20];};Personfn(Person

p){

return

p;}Person*fnPtr(Person*p){

return

p;}voidmain(){ Tdated1(1,2,2000); Tdated2(1,2,2021);

cout<<"****Person对象****"<<endl;

Personp1("张三",d1);

Personp2("李四",d1);

cout<<"****传递*Person对象****"<<endl;

fn(p1).print();

cout<<"****传递*Person对象指针****"<<endl;

fnPtr(&p2)->print();

cout<<"****main语句结束****"<<endl;}运行过程和结果在组合关联中,由于“整体”和“部分”的生命周期相同,在创建“整体”时需要同时创建“部分”,在删除“整体”时需要同时删除“部分”,创建和删除“部分”的职责自然而然地赋予了构造函数和析构函数。3.3.3使用代码实现聚合关联生命周期不同“部分”可以独立存在程序员的责任只维护连接不必维护对象语言编译器不提供编码实现语义【例3.8】类Motor和Wheel//Motor.hclass

Motor{public: Motor(intsn,floatfPower); ~Motor();

voidprint();

private:

intserialNumber;//产品序列号

floatpower;//发动机的排量};//Motor.cpp#include

<iostream>#include

"Motor.h"using

namespacestd;

Motor::Motor(int

sn,float

fPower){

cout<<"调用构造函数Motor("<<sn<<","<<fPower<<")"<<endl;

serialNumber=sn; power=fPower;}Motor::~Motor(){

cout<<"析构Motor:"<<serialNumber<<endl;}void

Motor::print(){ cout<<serialNumber<<","<<power;}【例3.9】类Motor和Wheel//Wheel.hclass

Wheel{public: Wheel(intsn,floatfSize); ~Wheel();

voidprint();private:

intserialNumber;//产品序列号

floatsize;//车轮大小};//Wheel.cpp#include

"Wheel.h"#include

<iostream>using

namespacestd;Wheel::Wheel(int

sn,float

fSize){

cout<<"调用构造函数Wheel("<<sn<<","<<fSize<<")"<<endl;

serialNumber=sn; size=fSize;}Wheel::~Wheel(){

cout<<"析构Wheel:"<<serialNumber<<endl;}void

Wheel::print(){

cout<<serialNumber<<","<<size;}【例3.9】类Car//Car.h#include"Wheel.h"#include

"Motor.h"

class

Car{public: Car(Motor&mMotor,Wheel**aWheel); ~Car();

Motor&set(Motor&depart);

Wheel&set(Wheel&depart,intposition);

voidprint();

private:

Wheel*wheel[4];//指向4个车轮

Motor*motor;//指向发动机};//Car.cpp#include

"Motor.h"#include

"Wheel.h"#include

"Car.h"#include

<iostream>using

namespacestd;Car::Car(Motor&mMotor,Wheel*aWheel[]):motor(&mMotor){ cout<<"调用构造函数Car(";

mMotor.print(); cout<<")"<<endl;

for(inti=0;i<4;i++){ wheel[i]=aWheel[i]; }}Car::~Car(){ cout<<"析构Car:"<<endl;

for(inti=0;i<4;i++){ //删除4个车轮对象

deletewheel[i]; }

deletemotor; //删除发动机对象}Motor&Car::set(Motor&depart){

Motor&rt=*motor;

motor=&depart;

returnrt;}Wheel&Car::set(Wheel&depart,int

position){

Wheel&rt=*wheel[position];

wheel[position]=&depart;

returnrt;}void

Car::print(){ cout<<"汽车\t发动机:"; motor->print(); cout<<"\t\t车轮:";

for(inti=0;i<4;i++){ wheel[i]->print(); cout<<"|"; } cout<<endl;}【例3.10】主程序//CarApp.cpp #include

"Motor.h"#include

"Wheel.h"#include

"Car.h"#include

<iostream>using

namespacestd;

voidmain(){ cout<<"***********创建发动机***********"<<endl;

Motor&m1=*(new

Motor(101,1.6));//为堆中的对象取了一个名称,以便后面使用

Motor&m2=*(new

Motor(102,2.0));

Motor&m3=*(new

Motor(103,1.6)); cout<<"***********创建车轮***********"<<endl;

const

intlen=10;

Wheel*wBase[len];

for(inti=0;i<len;i++){ wBase[i]=new

Wheel(201+i,10); } cout<<"***********创建汽车***********"<<endl;

Car&c1=*(newCar(m1,wBase)); c1.print(); Car&c2=*(newCar(m2,wBase+4)); c2.print(); cout<<"***********更换并报废部件***********"<<endl;

Wheel&w1=c1.set(*wBase[8],1);//换第一个车轮

delete&w1; //报废车轮,删除它

Motor&t=c1.set(m3);//换发动机

delete&t; //报废发动机,删除它 cout<<"***********报废汽车***********"<<endl;

delete&c1;

delete&c2; cout<<"***********删除库存中没有使用的车轮***********"<<endl;

deletewBase[9];}运行结果***********创建发动机***********调用构造函数Motor(101,1.6)调用构造函数Motor(102,2)调用构造函数Motor(103,1.6)***********创建车轮***********调用构造函数Wheel(201,10)调用构造函数Wheel(202,10)调用构造函数Wheel(203,10)调用构造函数Wheel(204,10)调用构造函数Wheel(205,10)调用构造函数Wheel(206,10)调用构造函数Wheel(207,10)调用构造函数Wheel(208,10)调用构造函数Wheel(209,10)调用构造函数Wheel(210,10)***********创建汽车***********调用构造函数Car(101,1.6)汽车

发动机:101,1.6车轮:201,10|202,10|203,10|204,10|调用构造函数Car(102,2)汽车

发动机:102,2车轮:205,10|206,10|207,10|208,10|***********更换并报废部件***********析构Wheel:202析构Motor:101***********报废汽车***********析构Wheel:201析构Wheel:209析构Wheel:203析构Wheel:204析构Motor:103析构Car:析构Wheel:205析构Wheel:206析构Wheel:207析构Wheel:208析构Motor:102析构Car:***********删除库存中没有使用的车轮***********析构Wheel:210

扩展:编写一些程序来专门管理内存中的对象练习调试通过例3.6的代码参照书中的思路,按照自己的理解重做例3.10总结及进一步学习分析:使用组合关联和聚合关联描述事物的构成设计:使用关联、连接等UML工具表示类及对象的内部关系编码:选用对象或指针(存储)实现组合关联及其连接,使用代码(逻辑)实现聚合关联3.4深入理解类及其对象(映射关系)3.5字符串进一步学习第3章关联与连接3.2关联的实现第3章关联与连接3.4深入理解类及其对象3.5字符串学习目标能够运用映射等知识解释类及其对象的本质能够运用组合关联等知识解释字符串的数据结构能够使用类、组合关联等UML工具封装字符串能够使用C++代码自定义字符串3.4深入理解类及其对象(映射关系)Students1(210101,"Randy",3.5)3.4深入理解类及其对象(映射)Students1(210101,"Randy",3.5)3.5字符串3.5.1数组中的概念及其关系3.5.2字符数组的语义3.5.3自定义字符串类myString3.5.1数组中的概念及其关系数组名数组元素元素类型内存结构逻辑结构3.5.2字符数组的语义语义:面向应用vs面向计算机实现方法:数据类型存储字符数组存储数组的指针3.5.2字符数组的语义动态数组:存储数组的指针3.5.3自定义字符串类myString封装为类动态数组【例3.11】字符串类myString//myString.hclass

myString{public: myString(chars[]); ~myString();

voidprint()const;

intgetLen()const;

char*getString()const; myString(const

myString&oldMyString);private:

char*ptrCharArray;

intlen;};//myString.cpp#include

"myString.h"#include

<iostream>using

namespacestd;

myString::myString(char

s[]){ len=strlen(s);

ptrCharArray=new

char[len+1]; strncpy(ptrCharArray,s,len+1); ptrCharArray[len]='\0';}myString::~myString(){

deleteptrCharArray;}void

myString::print()const{ cout<<ptrCharArray<<endl;}int

myString::getLen()const{

returnlen;}const

char*myString::getString()const{

returnptrCharArray;}myString::myString(const

myString&oldMyString){ len=oldMyString.getLen();

ptrCharArray=new

char[len+1]; strncpy(ptrCharArray,oldMyString.getString(),len+1);}【例3.12】类Person中使用类myString//Person.cpp#include

"myString.h"#include

<iostream>using

namespacestd;class

Person{public: Person(){} Person(myStringn):name(n.getString()){}

voidprint(){ cout<<"Person:"; name.print(); } Person(const

Person&oldPerson):name(oldPerson.name){}private:

myStringname;//表示到myString的组合关联};Personfn(Person

p){

return

p;}myStringfn(myStringp){

return

p;}voidmain(){ cout<<"****创建myString对象****"<<endl;

myStrings1("张三"); s1.print();

myStrings2(s1); s2.print();

cout<<endl<<"****传递*myString对象****"<<endl;

fn(s1).print();

cout<<endl<<"****创建Person对象****"<<endl;

Personp1("李四"); p1.print();

Personp2(s1); p2.print();

cout<<endl<<"****传递*Person对象****"<<endl; fn(p1).print();

cout<<endl<<"***堆中创建*Person对象****"<<endl;

Person*p3=new

Person("王五"); p3->print();

cout<<"****main语句结束****"<<endl;}练习调试通过例3.11和3.12的代码使用动态数组存储一个人的姓名,类Person的对象负责管理其中存储的姓名,并编程实现。总结及进一步学习分析:运用组合关联等知识抽象封装字符串设计:使用组合关联及连接等UML工具描述类myString的内部结构编码:使用C++编码实现字符串3.6链表进一步学习第3章关联与连接3.2关联的实现第3章关联与连接3.6应用举例:链表3.5字符串学习目标能够运用关联等知识解释链表的数据结构能够使用关联、连接等UML工具描述链表的数据结构能够解释封装链表的思路及方法能够使用C++编码实现链表3.6应用举例:链表【例3.13】使用链表管理学生#include

"myString.h"#include

"Student.h"

#i

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论