第7章类与对象_第1页
第7章类与对象_第2页
第7章类与对象_第3页
第7章类与对象_第4页
第7章类与对象_第5页
已阅读5页,还剩52页未读 继续免费阅读

下载本文档

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

文档简介

会计学1第7章类与对象7.1

面向对象的程序设计

面向对象的程序设计的核心是用类来抽象地描述所需解决的某类问题,用对象来代表所要解决的具体问题。类是一个概念,即数据类型;而对象是实例,即变量。

编程案例:

现有二个三角形,需要编程计算它们的周长和面积。三角形:

边长a;

边长b;边长c;

周长l;

面积s。某三角形:

边长3;

边长4;边长5;

周长12;

面积6。类:数据类型对象:变量第1页/共57页

面向过程的程序设计方法:

(1)定义函数fun求三角形的周长和面积。三角形的边长通过函数的参数传入;

(2)在主函数中用二组变量分别表示二个三角形的边长,并分别调用函数fun求得各三角形的周长和面积。缺点:数据之间没有关系,数据和功能之间没有联系。

面向对象的程序设计方法:

(1)

定义一个表示三角形的通用模块(类),描述三角形的数据(边长、周长和面积),以及求周长和面积的方法(函数);

(2)在主函数中用定义的类,说明二个变量(对象),并调用函数求三角形的周长或面积。优点:对象之间相对独立;内部自成一体,不但包含对象属性(数据),还包含数据的操作(函数)。7.1

面向对象的程序设计第2页/共57页7.2.1类

类是对某一类问题的抽象的描述。

某一类问题:在所关注的问题上是通用的;

抽象:只提取必要的信息。类定义的基本格式:

class类名{

private:

//私有成员

私有成员列表;

protected://保护成员

保护成员列表;

public:

//公有成员

公有成员列表;

};7.2

类与对象私有成员只能在类中直接访问;

保护成员可以在类中,及其派生类中直接访问;

公有成员允许在任何地方直接访问。设类的对象t有公有成员a和私有成员b,主函数中可直接使用t.a,但不能直接用t.b,只能间接访问。类的缺省访问特性是私有的,而结构体的缺省访问特性是公有的。第3页/共57页例7-1

定义一个求三角形的周长和面积的类TRI。classTRI{floata,b,c;

public:

set(floata1,floatb1,floatc1){a=a1;b=b1;c=c1;}

floatgirth(){return(a+b+c);}

floatarea();

};floatTRI::area()

{

floats,t;

t=girth()/2;

s=sqrt(t*(t-a)*(t-b)*(t-c));

returns;

}7.2.1类成员函数可以在类中直接定义,也可以在类中说明,类外定义。类外定义时,用类名和作用域运算符(::)说明其所属的类。第4页/共57页7.2.1类类定义的几点说明:(1)访问特性关键字出现的顺序和次数均没有限制,但同一访问特性成员应相对集中以增加程序的可读性;(2)与结构体定义相似,不能用关键字auto、register、extern说明成员的存储类型,不能初始化数据成员;(3)类体中直接定义的成员函数具有内联特性,类中说明类外定义的成员函数用inline说明才具有内联特性。(4)类成员具有类作用域,即类的成员类中处处可见,没有先后。

classmyclass{

public: voidf(){cout<<data;}

public: intdata;

};第5页/共57页对象

对象是类概念下的实例。类是对某一类问题的通用描述,只有对象才能表示具体的问题。类与对象的关系,类似于数据类型与变量的关系。1.对象的定义

定义对象的方法与定义结构体变量的方法相似,主要有3种:

(1)先定义类,再定义对象;

(2)定义类的同时,定义对象;

(3)不列出类名,直接定义对象。2.对象的使用

类体中直接使用类的非静态成员,类体外必须指明成员隶属的类。定义对象后,通过对象名和成员运算符“.”使用类的公有成员。7.2.2对象第6页/共57页例7-2

对象定义和使用

classA{

inta;

public:

intb;

voidset(intt1,intt2){a=t1;b=t2;}

voidprint(){cout<<a<<','<<b<<endl;}

intgeta(){returna;}

}a1;voidmain()

{Aa2;

a1.set(1,2);a2.set(5,10);a1.print();

cout<<a2.geta()<<',‘<<a2.b<<endl;}7.2.2对象对象成员的使用:成员运算符,注意成员数据与函数成员的区别;公有成员和私有成员的操作权限;对象成员相对独立,同类型对象赋值。12a1

a

ba2

a

b5

101

2a2=a1;程序输出为:

1,2

5,10第7页/共57页例7-3

对象的指针和引用

classB{

inta,b;

public:

voidset(intt1,intt2){a=t1;b=t2;}

voidprint(){cout<<a<<','<<b<<endl;}

};voidmain()

{Bb1,*p1=&b1,&b2=b1,*p2;

b1.set(5,10);p2=newB;*p2=b1;

b1.print();b2.print();

p1->print();p2->print();

deletep2;}7.2.2对象对象的指针、引用和动态对象;用指针操作对象成员的形式。程序输出为:

510

510

510

510第8页/共57页

程序中声明一个对象时,系统需要根据其所属的类的结构分配相应的内存空间;同时也可以对该对象的数据成员赋值,即初始化对象。当对象结束生命期时,系统需清理内存。这两部分工作由类的构造函数和析构函数来完成。7.3.1构造函数

构造函数是类中与类同名的一组特殊的成员函数。定义对象时,系统自动调用相应的构造函数,初始化所定义的对象。构造函数定义的基本格式为:

类名(形参列表){初始化数据成员语句}构造函数类中说明,类外定义格式为:

(1)类中说明:类名(形参列表);

(2)类外定义:类名::类名(形参列表)

{初始化数据成员语句}7.3构造函数与析构函数第9页/共57页例7-4

构造函数定义和调用

#include<iostream.h>classC{

inta,b;

public:

voidprint(){cout<<a<<'\t'<<b<<endl;}

};voidmain()

{

c1.print();

}7.3.1构造函数构造函数定义:公有;

造函数没有函数类型,也不是void类型;函数体中不能用return语句返回函数值。构造函数调用:自动、参数一致。程序输出为:

510

主函数中增加语句:

Cc1;//语法错误voidset(intt1,intt2){a=t1;b=t2;}Cc1;c1.set(5,10);C(intt1,intt2){a=t1;b=t2;}Cc1(5,10);第10页/共57页7.3.1构造函数关于构造函数的定义和使用,需注意以下几点:(1)构造函数中,数据成员的初始化可以在函数体内实现,也可以通过数据成员列表的方式实现。例如,上例中的构造函数可以写成如下形式:

C(intt1,intt2):a(t1),b(t2)

{}(2)在类中与类同名的成员函数一定是类的构造函数。(3)一个类可以有多个构造函数,但必须满足函数重载的原则。(4)任何一个类均有构造函数,任何一个对象生成时必定要调用相应的构造函数来初始化其成员。如果类中没有定义构造函数,系统编译时会自动产生一个空的构造函数,此时数据成员的值不确定。第11页/共57页7.3.2

缺省构造函数

缺省的构造函数主要有3种情况:编译系统自动生成的缺省构造函数

用户没有定义构造函数时,系统自动生成的没有参数、函数体内没有语句的构造函数。用户定义的没有参数的构造函数。用户定义的所有参数都有缺省值的构造函数。定义、使用缺省的构造函数时注意:编译系统自动生成的缺省构造函数仅用来生成对象,而不能初始化对象;只要用户定义了构造函数,编译系统将不再自动生成缺省的构造函数

。一个类中,最多有一个缺省的构造函数;但可能没有缺省的构造函数。第12页/共57页例7-5

缺省构造函数定义使用

#include<iostream.h>

classA{

inta;

public:

A(){a=1;}

voidprint(){cout<<a;}

};classB{

inta;

public:

B(intt1){a=t1;}

voidprint(){cout<<a;}

};7.3.2

缺省构造函数

classC{inta;

public:

voidprint(){cout<<a;}

};classD{inta;

public:

D(intt1=3) {a=t1;}

voidprint(){cout<<a;}

};voidmain(){

Aa1;//a1.a=1Bb1;//编译错误

Cc1;//c1没有初始化

Dd1,d2(5); //d1.a=3,d2.a=5

}A(intt1=1){a=t1;}//?C(){}Bb2();//说明无参函数b2调用缺省构造函数建立对象时,不能给对象提供参数。无法确定调用哪个构造函数。第13页/共57页7.3.3

拷贝构造函数

拷贝构造函数:以对象的引用作为函数参数,即用一个已存在的对象去初始化一个新建立的同类对象。主要有二种情况:缺省的拷贝构造函数

在用户没有定义拷贝构造函数时,系统自动生成一个缺省的拷贝构造函数,将用于提供初始数据的对象的成员值依次复制到新定义的对象中。用户定义的拷贝构造函数

用户自定义的、以该类对象引用为参数的构造函数。当用户定义了拷贝构造函数时,系统就不再自动生成缺省的拷贝构造函数。拷贝构造函数生成对象的方式:类名

新对象名(已有对象名);类名

新对象名=已有对象名;第14页/共57页例7-6

拷贝构造函数定义使用

#include<iostream.h>

classA{inta;

public:

A(intt){a=t;}

voidprint(){cout<<a;}

};classB{int*p;

public:

B(intt){p=newint(t);}

voidprint(){cout<<*p;}

voiddel(){deletep;}

};7.3.3

拷贝构造函数

voidmain(){

Aa1(1),a2(a1);

Bb1(5),b2=b1;

a1.print();a2.print();b1.print();b2.print();b1.del();b2.del();

}A(A

&t){a=t.a;}a1.a1a2.a1b1.p5b2.p5B(B

&t)

{p=newint(*t.p);}B(B

&t){p=t.p;}程序输出为:

11

55

a2.p=a1.p第15页/共57页7.3.4构造函数与成员初始化列表

当类的数据成员是引用类型、常量型或对象时,不能在构造函数体中用赋值语句直接初始化,而应以成员列表的形式在函数头部完成。使用时注意:初始化对象成员的基本形式:

类名(形参列表):对象名(实参列表)//对象成员初始化

{普通成员(基本变量)初始化}普通成员也可以在列表中初始化。初始化列表只是提供了相应成员的初始化形式和数据,并没有决定各个成员的初始化顺序。列表中成员的初始化顺序由类定义时成员的说明顺序决定。列表中的成员初始化完成后,再执行构造函数函数体,初始化其他成员。第16页/共57页例7-7对象成员初始化

#include<iostream.h>

classA{inta;

public:

A(intt){a=t;}

intgeta(){returna;}

};classB{inta,b;

Aa1;intc,d;

public:

B(intt):d(t++),a1(t++),a(t++)

{c=t++;b=t;}

voidprint()

{cout<<a<<b<<c<<d<<a1.geta()<<endl;}

};7.3.4构造函数与成员初始化列表voidmain(){

Bb1(1);b1.print();}程序输出为:

15432

初始化过程:

(1)列表中的成员

(2)函数体

语句顺序成员说明顺序:a→a1→d

:c→b第17页/共57页7.3.5析构函数

析构函数也是类的一种特殊成员函数,执行与构造函数相反的操作,用于撤销对象时的清理,如释放分配给对象的内存空间等。函数名由析构运算符“~”和类名组成。没有函数类型,不能用return返回值。没有参数,不能重载。由系统自动调用,调用顺序与构造函数相反。通常无需定义,系统自动生成的缺省析构函数为:

~类名(){}

当构造函数为类的指针成员分配了动态内存时,用户应定义析构函数,释放动态内存;此时,系统不再生成缺省的析构函数。第18页/共57页例7-8析构函数使用

#include<iostream.h>

#include<string.h>

classA{

char*s;public:

A(char*p);

~A();

voidprint(){

cout<<s<<endl;

}

};voidmain()

{Aa1("VisualC++"); a1.print();}7.3.5析构函数A::A(char*p){

s=newchar[strlen(p)+1];

strcpy(s,p);

cout<<"调用了构造函数\n";

}A::~A(){

delete[]s;

cout<<"调用了析构函数\n";

}程序输出为:

调用了构造函数

VisualC++

调用了析构函数第19页/共57页例7-9构造函数与析构函数使用

#include<iostream.h>classA;classB;voidmain(){ Aa1,a2(1),a3(a1); Bb1(2,3),b2;}classA{inta;public: A(intx){a=x;cout<<"构造函数A\n";} A(){a=0;cout<<"缺省构造函数A\n";} A(A&t){a=t.a+10;cout<<"拷贝构造函数A\n";} ~A(){cout<<a<<',';cout<<"释放A类对象\n";}};7.3.5析构函数程序输出为:

缺省构造函数A

构造函数A

拷贝构造函数A

构造函数A

构造函数B

缺省构造函数A

缺省构造函数B第20页/共57页例7-9构造函数与析构函数使用

classB{ intb; Aa1;public: B(intx,inty):a1(x) {b=y;cout<<"构造函数B\n";} B()

{b=5;

cout<<"缺省构造函数B\n";

} ~B()

{cout<<b<<',';

cout<<"释放B类对象\n";

}};7.3.5析构函数程序输出为:

5,释放B类对象

0,释放A类对象

3,释放B类对象

2,释放A类对象

10,释放A类对象

1,释放A类对象

0,释放A类对象第21页/共57页

类的各对象的数据相互独立,类的成员函数代码相同。成员函数如何区分其操作的数据所属的对象?

C++中,类的各个非静态成员函数中都有一个由系统提供的指针常量this,指向调用该成员函数的对象(当前对象),非静态成员函数中的成员均被隐含地施加了this指针,即类中缺省引用的非静态成员是this指针所指向的成员。如:

voidA::print(){cout<<a;}

即voidA::print(){cout<<this->a;}通常情况下,this指针由系统自动隐含使用。特定情况下,用户必须显式地使用this指针。7.4

this指针第22页/共57页例7-10this使用

#include<iostream.h>

classA{

inta,b;

public:

A(inta,intt)

{this->a=a;b=t;}Aadd(A&t)

{a=a+t.a;

b=b+t.b;

return*this;

}voidprint()

{cout<<a<<'\t'<<b<<endl;}

};7.4this指针voidmain()

{Aa1(1,2),a2(5,10);

a1.print();a2.print();a2=a1.add(a2);a1.print();a2.print();

}成员函数中直接使用的成员,通常等同于this->成员。程序输出为:

12

510

612

612this->a=this->a+t.a;根据局部优先原则,参数a。第23页/共57页

同一个类的不同对象之间的普通成员是相互独立的,即可以有不同的数据。而静态成员则可实现不同对象之间的数据和函数共享。在类的定义中,用关键字static说明的成员为静态成员,分静态数据成员和静态成员函数。7.5.1静态数据成员

类的静态数据成员不属于特定对象,而属于类;必须在类中说明的同时,在类外定义;改变了一个对象静态数据成员的值,则所有其他对象的相应静态数据成员的值均随之改变。7.5

静态成员A::ba24aa11a0classA{public:inta;staticintb,c;

A(intx,inty,intz){a=x;b=y;c=z;}};

intA::b,A::c=10;

Aa1(1,2,3),a2(4,5,6);A::c102356第24页/共57页例7-11类的静态数据成员的定义与使用

#include<iostream.h>

classA{

inta;

staticintb,c;public:

A(intt){a=t;}voidadd()

{a++;b++;c++;}

voidprint()

{cout<<a<<'\t';

cout<<b<<'\t'<<A::c<<endl;

}

};intA::b,A::c=5;7.5.1静态数据成员voidmain(){Aa1(0),a2(3);a1.print();a2.print();a1.add(); a1.print();a2.print();}静态数据成员缺省初值为0;类中引用性说明格式为:

static数据类型成员名;类外定义格式为:

数据类型类名::成员名(初值);

数据类型类名::成员名=初值;程序输出为:

005

305

116

316第25页/共57页

在类体中用关键字static修饰的函数称为类的静态成员函数。静态成员同样为该类的所有对象所共有,不属于某个特定的对象,函数内部没有this指针。静态成员函数可以类体中说明,类体外定义。类体中说明时必须用static修饰,类体外定义时不能用static修饰。静态成员函数中访问成员

只能直接访问类的静态成员,等同于类名::静态成员;间接访问类的非静态成员,等同于类外访问,即对象.非静态成员。普通函数中访问静态成员

(1)

非静态成员函数:通过this指针,或“类名::”访问。

(2)

外部函数:可以指明其所属的对象(对象.静态成员),也可以指明其所属的类(类名::静态成员)。7.5.2静态成员函数第26页/共57页例7-12类的静态成员函数的定义与使用

#include<iostream.h>

classS{

inta;staticintb;public:

S(intt){a=t;}

staticvoidadd1()

{b++;//等同于S::b++

a++;//等同于this->a++,错误!

}

staticvoidadd2(St);

voidprint(){cout<<a<<'\t'<<b<<endl;}

};intS::b=5;

voidS::add2(St){t.a++;b++;}7.5静态成员voidmain(){S::add1();//指明所属类

Ss1(0);s1.print();s1.add2(s1);//指明所属对象

s1.print();}删除错误行后,程序输出为:

06

07通过this访问静态成员也可通过类名::访问,即S::b第27页/共57页7.6

常对象与常成员

用关键字const修饰类的成员或对象,在程序运行期间是不可改变的,称为常成员或常对象。1.常数据成员在类中说明时加关键字const的数据成员。除静态常数据成员以外,类的常数据成员只能在类的构造函数中通过初始化列表的方式初始化,不能通过赋值的形式初始化。类的静态常数据成员只能在类外定义时初始化。常数据成员只能被读取,不能被修改。第28页/共57页例7-13常成员数据的定义与使用

#include<iostream.h>

classT{

inta;

intconstb;//常成员,constintb;

constint&c;

//常成员引用

conststaticintd;

//静态常成员public:

T(intt1,intt2):b(t2),c(a)

{a=t1;}voidprint(){cout<<a<<b<<c<<d<<endl;}

voidfun(){a++;}//不可改变b、c、d

};constintT::d=15; voidmain(){Tt1(5,10);t1.print();t1.fun();t1.print();}程序输出为:

510515

6106157.6

常对象与常成员非常数据成员不可以引用常数据成员,常数据成员可以引用非常数据成员第29页/共57页7.6

常对象与常成员2.常成员函数

用关键const说明的成员函数称为常成员函数:

函数类型函数名(形参表表)const;关键字const加在函数头部的最后,而不是加在最前面。如果加在最前面,则表示函数的类型是一个常量。关键字const是函数类型的一个组成部分,原型说明时不可省略。常成员函数不能修改本类的数据成员,也不能调用其他非常成员函数。关键字const作为函数重载时区分不同函数的标志。重载的原则是:常对象调用常成员函数,一般对象调用一般成员函数。第30页/共57页7.6

常对象与常成员3.常对象

定义时通过const修饰的对象为常对象,其定义形式如下:

类名const

对象名;

或:

const

类名对象名;常对象定义时必须初始化;常对象的数据成员不允许被改变;通过常对象,只能调用类的常成员函数。非常对象,既可以调用非常成员函数,也可以调用常成员函数。第31页/共57页例7-14常成员函数与常对象使用

#include<iostream.h>

classA{

inta;

intconstb;

public:

A(intt1,intt2):b(t1)

{a=t2;}

voidprint()const;voidprint(){cout<<a-b<<endl;}

voidadd(intt){a+=t;}

};voidA::print()const

{cout<<a+b<<endl; } voidmain(){constAa1(5,10);Aa2(1,2); a1.add(3);//编译错误

a2.add(3);a1.print();a2.print();}程序输出为:

15

47.6

常对象与常成员常对象只能引用常成员第32页/共57页例7-15根据键盘输入的身份证号计算相应的年龄。程序设计从身份证号码中提取出生年份,并与当前年份相减即可得到年龄。从身份证号码中提取出生年份的方法是把身份证号码作为一个字符串,然后把指定位置(从第7位到第10位)的数字字符转换为一个整数。当前年份可以通过调用C++库函数time来获取。函数time返回time_t格式的系统当前日期,然后调用库函数localtime将其转换为一个tm类型的结构体变量,其中成员tm_year中存放以1900年为起点的年份数。类型time_t和结构体tm都在系统文件time.h中定义。7.7程序设计举例第33页/共57页

源程序代码

#include<iostream.h>#include<time.h>#include<string.h>classID{

charid[20];

//

身份证号

intage;

//

年龄public:

ID(char*id){strcpy(this->id,id);}

intval(char*p,inti,intj);//从身份证中提取出生日期

voidfun();//计算年龄

voiddisplay()

{ cout<<"身份证号:"<<id<<endl; cout<<"年龄:"<<age<<endl;

}};7.7程序设计举例voidmain(){chars[20];cout<<"请输入身份证号:";cin>>s;IDid(s);id.fun();id.display();}第34页/共57页

源程序代码

intID::val(char*p,inti,intj){

//从身份证中提取出生日期

//将字符串从第i个字符开始的j个连续数字转换为一个整数

intn=0,k=i+j;

while(i<k){ n=n*10+*(p+i)-'0';

i++;

}

return(n);}7.7程序设计举例voidID::fun() //计算年龄{intyear=val(id,6,4);

//以下2行获取当前时间,并存入tm类型的结构体变量t中

time_ttimer;timer=time(0);tmt=*localtime(&timer);age=t.tm_year+1900-year;}第35页/共57页例7-16定义一个数组类,实现将二维数组各行元素排序、各列元素排序、全体元素按内存顺序排序等功能。程序设计

classArray{

inta[4][5];

public:

Array(intt[][5]);

voidprint();

voidfun1(); //行排序

voidfun2(); //列排序

voidfun3(); //内存顺序排序

};7.7程序设计举例第36页/共57页程序设计voidmain(){intdata[4][5]={…};Arraya1(data),a2(data);cout<<"\n原数组:\n";a1.print();cout<<"\n行排序:\n";a1.fun1();a1.print();cout<<"\n列排序:\n";a1=a2;a1.fun2();a1.print();cout<<"\n内存顺序排序:\n";a1=a2;a1.fun3(); a1.print();}7.7程序设计举例第37页/共57页例7-17定义一个类,将一组数组按给定的行列表示成一个二维数组。程序设计

classArray{

int*p;

//指针成员表示一组数组

intm,n;

//m、n分别为二维护数组的行数和列数

public:

Array(int*t,inta,intb);

~Array()

{

delete[]p;

}

//撤销动态内存

intget(inti,intj);//取数组下标为[i][j]的元素

voidprint();

};voidmain()

{constinti0=3,j0=5;intdata[i0*j0]={…};

Arraya1(data,i0,j0);a1.print();

}7.7程序设计举例第38页/共57页例7-18定义一个将学生类,将一组学生的数据存入对象数组,并根据成绩学生信息排序。要求每个同学的信息中均含有该班成绩的总分和平均分。程序设计

classSTU;//表示一个学生的类

voidinput(STUt[]);

voidsort(STU*p[]);

voidprint(STU*t[]);

voidmain()

{

STU*p[5],s[5];

input(s);

for(inti=0;i<STU::get_count();i++)p[i]=s+i;

sort(p);

print(p);

}7.7程序设计举例第39页/共57页程序设计

classSTU{

floatscore;

charname[15];

staticintcount;

staticfloatsum,average;

public:

STU(){

count++;

}

~STU(){

count--;}

voidinput();

voidprint(){

cout<<name<<":"<<score<<endl;

}

staticintget_count(){

returncount;

}

staticfloatget_sum()

{

returnsum;

}

staticfloatget_average(){

returnaverage;

}

floatget_score()

{

returnscore;

}

};7.7程序设计举例第40页/共57页程序结构

面向对象的编程有两部分组成:

(1)类的定义;

(2)类的测试

主函数中用定义的类说明对象,然后通过对象调用有关的成员函数。构造函数

用形参初始化数据成员。根据数据成员,分3种情况:

(1)普通变量作成员;

(2)数组作成员;

(3)指针作成员。析构函数

释放构造函数中分配的动态空间,只有数据成员为第3种情况时才需定义。7.7程序设计举例第41页/共57页输出函数

根据要求,按3种数据成员采用适当的方法输出数据成员。功能函数

完成题目提出的操作要求,如排序、取字符串中的数字、调整元素(行列)位置等。测试程序(主函数)

(1)定义对象时注意

类的数据成员为非字符数组时,对象的参数只能是与形参对应的数组名;而数据成员为字符数组时,对象的参数除了数组名外,还可以是字符串常量。

(2)调用成员函数时注意

调用语句基本格式为:对象.成员函数(实参);

注意成员函数调用的顺序和参数。7.7程序设计举例第42页/共57页数据成员为普通变量

构造函数中直接把实参赋给数据成员。数据成员为一维数组

构造函数的形参为指针变量(一维数组)和整型变量(数组大小),函数体中通过循环语句把形参赋给数据成员,其他功能函数体中通过循环语句操作一维数组。数据成员为字符数组

构造函数的形参为指针变量(字符数组),通过字符串处理函数(赋值)、循环语句等方法操作字符数组。数据成员为二维数组

构造函数的形参为行指针(二维数组)和整型变量(二维数组行数),通过二层循环语句操作二维数组。7.7程序设计举例第43页/共57页数据成员为指针变量用new为指针变量分配动态空间;分配动态空间后,指针变量等同于数组。然后用操作数组的方法操作指针变量所指指动态动态空间,注意指针变量所指位置,尽可能不要移动。如:

classmycalass{

int*p,num;

char*str;

public:

myclass(inta[],intn,char*s)

{num=n;p=newint[num];

for(inti=0;i<num;i++)p[i]=a[i];

str=newchar[strlen(s)+1];strcpy(str,s);

}7.7程序设计举例第44页/共57页1.试定义一个类STR,将字符串中的数字字符依次全部移到字符串的后半部。具体要求如下:

(1)私有数据成员char*p;p为待处理的字符串。

(2)公有成员函数STR(char*s);构造函数,用s初始化数据成员p。voidmove(char&t1,char&t2);交换两个字符的位置。voidfun();根据题意处理字符串p。算法要求:从左到右依次对字符串p的每个字符进行检测,如果在数字字符的右侧有非数字字符,则通过调用函数move()将该非数字字符与前一个字符进行交换,直到前一个字符为非数字字符为止。~STR();析构函数,撤销所占用的动态存储空间。voidprint();输出数组中的所有元素。

(3)在主函数中对类STR进行测试。7.8习题第45页/共57页7.8习题voidSTR::fun(){for(char*p1=p;*p1;p1++){if(*p1>'9'&&*p1<'0')continue;char*p2=p1;while(*p2>='0'&&*p2<='9')p2++;if(!(*p2))break;while(*p2&&p2>p1){move(*p2,*(p2-1));p2--;}}}voidmain()

{STRt(“12AS353hjk56”);

t.print();t.fun();t.print();

}#include<iostream.h>#include<string.hclassSTR{char*ppublic:STR(char*s){p=newchar[strlen(s)+1];strcpy(p,s);}voidfun();voidmove(char&t1,char&t2){chart=t1;t1=t2;t2=t;}voidprint(){cout<<p<<endl;}~STR(){delete[]p; }};第46页/共57页2.试定义一个类Array,将二维数组的各列依次循环右移n次。具体要求如下:

(1)私有数据成员inta[4][4];待处理的数组。

(2)公有成员函数Array(intt[][4],intn);构造函数,用数组t初始化数组a,n表示数组的行数。voidright();将数组a各列循环右移1次,其中,数组的最右一列移至数组的最左边。voidrmove(intn);利用成员函数rig

温馨提示

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

评论

0/150

提交评论