当前位置:文档之家› C++实验20 友元函数、静态成员和虚函数

C++实验20 友元函数、静态成员和虚函数

C++实验20 友元函数、静态成员和虚函数
C++实验20 友元函数、静态成员和虚函数

实验20 友元函数、静态成员和虚函数

一、实验目的和要求

1.理解友元函数的特性,掌握友元函数的定义方法。

2.理解虚函数的特性。

3.掌握利用虚函数实现动态多态性的解题方法。

4.掌握静态数据成员的特性。

5.进一步锻炼针对类的编程能力。

二、实验准备

知识点

1.友元函数与友元类

(1)C++中的________突破了类的封装性,给予其它的类或非成员函数访问类的私有、保护成员。

(2)友元必须在类中先用关键字________声明。

(3)友元函数________类的成员函数。(是/不是)

(4)在类外定义友元函数时,函数名前________加关键字friend,________加类名及域运算符”::”。(需要/不需要)

(5)要想类B的所有成员函数均能访问类A的所有成员,则应将类B声明为类A的_______。2.静态成员

(1)同类的不同对象________成员函数代码空间,________一般数据成员分配的空间,但________静态成员分配的空间。(共享/不共享)

(2)静态数据成员在类中用关键字________声明,________(能/不能)通过构造函数进行初始化。

(3)公有静态成员可以直接通过________访问。

(4)静态成员函数________访问类中的非静态成员。(能/不能)

(5)静态成员函数________隐含的this指针。(含有/不含有)

3.多态性的分类及区别

(1)多态性就是当不同对象接受到相同消息时能产生不同动作,它常用__________或__________来实现。

(2)多态性分为两种:_____________(编译时多态)和_____________(运行时多态)。4.虚函数

(1)声明虚函数的方法是在基类中的成员函数原型前加上关键字__________,并在派生类中重新实现该成员函数。

(2)虚函数必须存在于类的继承环境下,它的使用方法是:通过__________或__________访问虚函数,该虚函数属于哪个类,就访问哪个类。

(3)同一组虚函数要求__________完全相同,如果不同,这组函数将转换为普通的_________关系。

5.纯虚函数和抽象类

(1)__________是一个在基类中说明的虚函数,但无函数实现部分,要求在派生类中实现。(2)纯虚函数的声明方法是将________置于虚函数的函数原型末尾。

(3)包含纯虚函数的类称之为__________。

(4)抽象类只能用作其它类的________,不能建立抽象类的________,但可以声明抽象类

的________或________,通过它们可以调用抽象类中的非纯虚函数。

?课前练习题

1.若需要将函数”void f();”声明为类A的友元函数,则应在类A的定义中加入一条语句:_______________________。

2.下面有关一个类的友元函数的叙述中,正确的是。

A.允许在类外访问类中除私有成员以外的任何成员

B.允许在类外访问类中的任何成员

C.友元函数也是该类的成员

D.友元函数的定义必须放在该类的公有部分

3.虚函数。

A.可实现静态多态性B.可实现动态多态性

C.不能实现多态性D.既可实现静态多态性,又可实现动态多态性

4.函数重载属于两种多态性中的哪一种:。

5.以下程序输出的第一行是,第二行是,第三行是。

# include

class T{public:static int x ; };

int T::x=1;

void main(void)

{

T a,b;a.x=10;b.x=20;

cout<<"a.x="<

}

6.以下程序输出结果的第一行是,第二行是。

# include

class X

{

public: virtual void f(){ cout <<"aa\n";}

};

class Y: public X

{

public: void f(){cout<<"bb\n";}

};

void main(void)

{

Y y,*xy=&y;X *xp=&y;

xy –>f(); xp–>f();

}

?分析

1.有以下程序:

#include

class A

{

int a,b;

static int c;

public:

A(int x){a=x;}

void f1(float x){b=a*x;}

static void setc(int x){c=x;}

int f2(){return a+b+c;}

friend void f3(A &); //行C

};

int A::c=100;

void f3(A &t){t.c+=10;} //行D

void main()

{

A a1(1000),a2(2000); //行A

a1.f1(0.25);

a2.f1(0.55);

A::setc(400); //行B

f3(a1); //行E

cout<<"a1="<

}

请回答问题:

①执行行A后,a1.c=________,a2.c=________,A::c=________。

②执行行B后,a1.c=________,a2.c=________,A::c=________。

行B可否改成A::c=400;?为什么?________________________________。

③从行C中函数f3的原型看,行D的void前需不需要加上friend?________________。

④c为类A的私有成员,但行D中为何通过t能访问成员c?_________________________。

⑤执行行E后,a1.c=________,a2.c=________,A::c=________。

⑥程序输出:________________________。上机验证输出结果。

2.有以下程序:

#include

class X

{

int m;

public:

X(int a=0){m=a;}

void virtual f(){cout<

void virtual g(){cout<

};

class A: public X

{

int n;

public:

A(int a):X(100) {n=a;}

void f(){cout<

void g(int a=0){cout<

};

void main(void)

{

A a(10);

X *p=&a; //行C

p->f(); //行A

p->g(); //行B

}

请回答问题:

①因main函数中的p为基类指针,所以本程序考查的可能是赋值兼容性规则或虚函数。类X和类A的函数f是一组虚函数,则行A考查的是________,输出结果:________。类X 和类A的函数g不是一组虚函数,是函数的________,则行B考查的是______________,调用的是类_____的g函数,其输出结果为:________。

②将行B改为p->g(1);,程序运行时有什么问题?___________________________。

③将行A改为p->X::f();,其输出结果为:________。

④将行C改为A *p=&a;,按照________规则,行A调用类____的f函数,输出________,行B调用类____的g函数,输出_________。

⑤将行C改为A *p=&a;后,要想调用基类X的f函数和g函数,行A应改为_______________,行B应改为_______________。

⑥如果将行D中的int a=0改为int a,行C改为A *p=&a;,则程序运行时有什么问题?___________________________。

三、实验内容

1.根据公式

h

k

n

i

i

n

i

h

i

n

i

i

k

i

x

n

x

x

x

y

+

=

=

=

?

?

?

?

?

?

?

?

?

?

?

?

-

=∑

1

1

1

1

)

ln.

(

计算y的值。其中∑表示求各项的和,∏

表示求各项的积。定义一个类F,实现上述功能。具体要求如下:

(1)私有数据成员

●double x[5]:存放x i(i=1,2,3,4,5)的值,x i不能为0。

●int n,k,h:公式中对应的变量,n不能为0。

●double y:存放计算结果。

(2)公有成员函数

●F(double a[], int _n, int _k, int _h):构造函数,分别初始化x、n、k、h。

●void calc():根据公式计算y的值。

(3)友元函数

●void print(F f):输出对象f所有数据成员。

(4)在主函数中对该类进行测试。测试数据x i取3.2、-2.5、-4.2、3.6、5.2,n取5,k取3,h取4,测试结果y=2.59513×1040。注意公式中用到的函数( 乘方、对数、绝对值、平方根)请在头文件math.h中查找。正确的输出结果如下:

3.2 -2.5 -

4.2 3.6

5.2

5 3 4

2.59513e+040

2.自守数定义:一个自然数的平方的尾数等于该数本身。例如:252=625,762=5776,93762=87909376,则25、76、9376均是自守数。试建立一个类Self,求出指定范围内的自守数,具体要求如下:

(1)私有数据成员

●int a[20]:存放求出的自守数。

●int m , n , p:m、n存放自守数的取值范围,p存放求出的自守数的个数。

(2)公有成员函数

●构造函数Self(int , int):初始化成员数据m、n。

●void process():根据给定的m、n的值,求出界于m、n之间(包括m、n本身)的所有自守数及其个数。

●void print():输出求出的自守数及其个数。

(3)在主函数中对该类进行测试。测试数据:m=1,n=110。

3.编写一个通用程序,将二维数组含有最大元素的列与第0列元素对调。例如,原数组和调换后的目标数组为

1 5 9 8 9 5 1 8

7 8 3 2 -->对调后--> 3 8 7 2

1 6 8 1 8 6 1 1

试建立一个类MAT,用于完成该功能。具体要求如下:

(1)私有数据成员

●int m,n:存放二维数组实际的行数和列数。

●int a[40][40]:用于存放原始数组和目标数组。注意:在此,将数组定义得稍大,实际

只用部分数组空间,即只用数组的前m行,每行只用前n列的空间。

(2)公有成员函数

●MAT(int y[][40],int rows,int cols):构造函数,用rows、cols分别初始化m、n,用数组y的值初始化数组a。

●void change():完成调换,注意必须是针对m行n列的二维数组的通用算法。

●void output():按二维方式输出数组。

(3)在主函数中定义二维数组b[40][40],存放原始数据,用上述数据初始化该数组b。定义一个MA T类的对象mtx,用数组b及数组的实际行数和列数初始化对象mtx,完成对该类的测试,并输出调换前后的二维数组数据。

4.建立一个存储和处理字符串的类DelCharStr。

(1)私有数据成员

●char *s:字符串的首地址。

●int len:该字符串的长度值。

(2)公有成员函数

●构造函数:动态申请存储字符串所需内存空间,并且即能用指定的字符串也能用默认的值0为所声明的对象进行初始化。

●析构函数:释放字符串所用的内存空间。

●void setstr(char *sn):重新设置str的值。

●viud showstr():显示字符串。

●int getstrlen():返回字符串长度值。

●void delchar(char ch):在字符串中查找并删除指定的字符。

(3)按以下要求编写程序测试该类。

●定义DelCharStr对象s1,初始值为”student”。

●输出s1中的字符串和长度值。

●从s1字符串中删除字符’t’,输出s1中的字符串和长度值。

●将”teacher”重新赋值给s1,输出s1中的字符串和长度值。

四、课后练习题

1.若需要将类B的成员函数”void f();”声明为类A的友元函数,则应在类A的定义中加入一条语句:_______________________。

2.若需要将类B声明为类A的友元类,则应在类A的定义中加入一条语句:______________。3.关于友元函数的说法,哪一个说法是错误的?_________。

A. 友元函数不是成员函数

B. 友元函数只能在类的public部分声明

C.友元函数需要在类内说明 D. 友元函数可以直接访问类的私有成员

4.下列叙述中不正确的是。

A.含纯虚函数的类为抽象类B.不能直接由抽象类建立对象

C.抽象类不能作为派生类的基类D.纯虚函数没有其函数的实现部分5.以下关于运行时的多态性的叙述中,不正确的是。

A.运行时的多态性要通过虚函数来实现

B.运行时的多态性要通过指向基类的指针来实现

C.运行时的多态性是在编译时确定其要执行的函数

D.运行时的多态性是在执行过程中根据具体被操作的对象来确定要运行的函数

6.下以程序输出的第二行是,第三行是。

# include

class E

{

int x;static int y;

public:

E(int a){x=a;y+=x;}

void Show(){cout<

} ;

int E::y=100;

void main(void)

{

E e1(10); e1.Show();

E e2(50); e2.Show(); e1.Show();

}

7.以下程序输出的第二行是,第四行是。

# include

class A

{

int i;

public:

static int count;

A(int a =0)

{

i=a+count;

count++; cout<

}

};

int A::count=0;

void main(void)

{

A a(100);

A b;

A c(200);

cout<<"count="<

}

8.以下程序输出的第一行是,第二行是。

# include

class X

{

public:

void virtual f(){cout<<"X:11"<

void virtual g(){cout<<"X:22"<

};

class A: public X

{

public:

void f(){cout<<"A:33"<

};

class B: public A

{

public:

void f(){cout<<"B:44"<

void g(int i=0){cout<<"B:55"<

};

void main(void)

{

B b;X *px=&b;

px–>f();px–>g();

}

9.以下程序输出的第一行是,第三行是。

# include

class A

{

int x, n;int mul;

public:

A(int a, int b) {x=a; n=b; mul=1;}

virtual int power(void)

{

mul=1;

for(int i=1;i<=n; i++)mul*=x;

return mul;

}

void show(void)

{ cout<

};

class B: public A

{

int y, m;

int p;

public:

B(int i, int j, int k, int h): A(i, j) {y=k; m=h; p=10;}

int power(void)

{

p=1;

for(int i=1; i<=m;i++)p*=y;

return p;

}

void show(void)

{ A∷show(); cout<

};

void fun(A*f)

{cout<power()<<'\n';}

void main()

{

A a(5, 3);

B b(2,4,3,3);

fun(&a); fun(&b);b.show();

}

10.以下程序输出的第一行是,第二行是。

# include

class Shape

{

public:

Shape( ){}

virtual float Area( )=0;

};

class Circle:public Shape

{

float r;

public;

Circle(float c){r=c;}

float Area(){return 3*r*r;}

};

class Rectangle:public Shape

{

float h,w;

public:

Rectangle(float c,float d){h=c;w=d;}

float Area(){return h * w;}

};

void fun(Shape * s) {cout<Area()<<'\n';}

void main(void)

{

Circle c(4);

fun(&c);

Rectangle r(5,2);

fun(&r);

}

静态函数

C程序一直由下列部分组成: 1)正文段——CPU执行的机器指令部分;一个程序只有一个副本;只读,防止程序由于意外事故而修改自身指令; 2)初始化数据段(数据段)——在程序中所有赋了初值的全局变量,存放在这里。 3)非初始化数据段(bss段)——在程序中没有初始化的全局变量;内核将此段初始化为0。 4)栈——增长方向:自顶向下增长;自动变量以及每次函数调用时所需要保存的信息(返回地址;环境信息)。 5)堆——动态存储分。 在全局变量之前加上关键字static,全局变量就被定义成为一个全局静态变量。1)内存中的位置:静态存储区(静态存储区在整个程序运行期间都存在)2)初始化:未经初始化的全局静态变量会被程序自动初始化为0(自动对象的值是任意的,除非他被显示初始化) 3)作用域:全局静态变量在声明他的文件之外是不可见的。准确地讲从定义之处开始到文件结尾。 好处: 定义全局静态变量的好处: <1>不会被其他文件所访问,修改 <2>其他文件中可以使用相同名字的变量,不会发生冲突。 局部静态变量 在局部变量之前加上关键字static,局部变量就被定义成为一个局部静态变量。1)内存中的位置:静态存储区 2)初始化:未经初始化的全局静态变量会被程序自动初始化为0(自动对象的值是任意的,除非他被显示初始化) 3)作用域:作用域仍为局部作用域,当定义它的函数或者语句块结束的时候,

作用域随之结束。 注:当static用来修饰局部变量的时候,它就改变了局部变量的存储位置,从原来的栈中存放改为静态存储区。但是局部静态变量在离开作用域之后,并没有被销毁,而是仍然驻留在内存当中,直到程序结束,只不过我们不能再对他进行访问。 当static用来修饰全局变量的时候,它就改变了全局变量的作用域(在声明他的文件之外是不可见的),但是没有改变它的存放位置,还是在静态存储区中。 3.静态函数 在函数的返回类型前加上关键字static,函数就被定义成为静态函数。 函数的定义和声明默认情况下是extern的,但静态函数只是在声明他的文件当中可见,不能被其他文件所用。 定义静态函数的好处: <1>其他文件中可以定义相同名字的函数,不会发生冲突 <2>静态函数不能被其他文件所用。存储说明符auto,register,extern,static,对应两种存储期:自动存储期和静态存储期。auto和register对应自动存储期。具有自动存储期的变量在进入声明该变量的程序块时被建立,它在该程序块活动时存在,退出该程序块时撤销。 关键字extern和static用来说明具有静态存储期的变量和函数。用static声明的局部变量具有静态存储持续期(static storage duration),或静态范围(static extent)。虽然他的值在函数调用之间保持有效,但是其名字的可视性仍限制在其局部域内。静态局部对象在程序执行到该对象的声明处时被首次初始化。 由于static变量的以上特性,可实现一些特定功能。 1.统计次数功能 声明函数的一个局部变量,并设为static类型,作为一个计数器,这样函数每次被调用的时候就可以进行计数。这是统计函数被调用次数的最好的办法,因为这个变量是和函数息息相关的,而函数可能在多个不同的地方被调用,所以从调

C++类中的静态成员变量和静态成员函数的作用

数据成员可以分静态变量、非静态变量两种. 静态成员:静态类中的成员加入static修饰符,即是静态成员.可以直接使用类名+静态成员名访问此静态成员,因为静态成员存在于内存,非静态成员需要实例化才会分配内存,所以静态成员不能访问非静态的成员..因为静态成员存在于内存,所以非静态成员可以直接访问类中静态的成员. 非成静态员:所有没有加Static的成员都是非静态成员,当类被实例化之后,可以通过实例化的类名进行访问..非静态成员的生存期决定于该类的生存期..而静态成员则不存在生存期的概念,因为静态成员始终驻留在内容中.. 一个类中也可以包含静态成员和非静态成员,类中也包括静态构造函数和非静态构造函数.. 分两个方面来总结,第一方面主要是相对于面向过程而言,即在这方面不涉及到类,第二方面相对于面向对象而言,主要说明static在类中的作用。 一、在面向过程设计中的static关键字 1、静态全局变量 定义:在全局变量前,加上关键字static 该变量就被定义成为了一个静态全局变量。 特点: A、该变量在全局数据区分配内存。 B、初始化:如果不显式初始化,那么将被隐式初始化为0(自动变量是随机的,除非显式地初始化)。 C、访变量只在本源文件可见,严格的讲应该为定义之处开始到本文件结束。 例(摘于C++程序设计教程---钱能主编P103)://file1.cpp //Example 1 #include void fn(); static int n; //定义静态全局变量 void main() {

n=20; cout <

实验五-静态路由配置

实验五-静态路由配置

南昌大学实验报告 学生姓名:学号:专业班级: 实验类型:□验证■综合□设计□创新 实验日期:实验成绩: 实验五静态路由配置实训 一、实验目的 ●进一步掌握路由器配置命令的使用 ●熟悉静态路由与默认路由的配置命令 ●熟悉tracert路由跟踪命令 二、实验设备及条件 ●运行Windows 操作系统计算机一台 ●Cisco 1840路由器两台,RJ-45转DB-9反 接线一根,串口线一根 ●超级终端应用程序或Cisco Packet Tracer 软件 三、实验原理 3.1 实训原理 路由器属于网络层设备,能够根据IP包头的信息,选择一条最佳路径,将数据包转发出去,以实现不同网段的主机之间的互相访问。选择最

佳路径的策略即路由算法是路由器的关键所在。 3.1.1 路由器的工作原理 为了完成路由选择工作,在路由器中保存着各种传输路径的相关数据——路由表(Routing Table),供路由选择时使用。打个比方,路由表就像我们平时使用的地图一样,标识着各种路线,路由表中保存着子网的标志信息、网上路由器的个数和下一个路由器的名字等内容。路由表可以是由系统管理员固定设置好的,也可以由系统动态修改,可以由路由器自动调整,也可以由主机控制。 路由表的项目一般含有五个基本字段:目的地址、网络掩码、下一跳地址、接口、度量。在进行路由选择时,路由器按照直接路由->特定主机路由->特定网络路由->默认路由的顺序讲IP 包头与路由表项进行匹配。 -直接路由项是指:该表项的“目的地址” 所在网络与路由器直接相连。 -间接路由项是指:该表项的“目的地址” 所在网络与路由器非直接相连。 -特定主机路由项是指:该表项的“目的地址”字段是某台特定主机的IP地址。

实验八 静态数据成员和静态函数成员

实验八静态数据成员和静态函数成员 任务一: 1、了解多文件工程 本次实验需要创建一个工程,此工程由三个文件组成 1)头文件client.h ——类的声明 2)源文件client.cpp——成员函数的定义 3)源文件test.cpp——main()函数的定义 2、了解CLIENT类 本次实验的主角是CLIENT(客户机)类。在实际生活中,计算机网络的应用模式为client/server(客户机/服务器)模式。情况很简单,即多台客户机与一台服务器连接,服务器为客户机提供服务。 3、实验任务 1)阅读程序代码,仔细分析CLIENT类的各数据成员及函数成员,写出分析结果 2)创建多文件工程,编译并运行 3)为main()函数的各条语句增加注释 4)将数据成员ServerName改为非静态,其它类成员的静态属性不变。 修改程序代码,使客户机a连接到另一台服务器M。(b仍与N连接) 任务二: 生成一个储蓄类CK。用静态数据成员表示每个存款人的年利率lixi。类的每个对象包含一个私有数据成员cunkuan,表示当前存款额。提供一个calLiXi()成员函数,计算利息,用cunkuan乘以lixi除以12取得月息,不计复利,并将这个月息加进cunkuan中。提供设置存款额函数set()。提供一个静态成员函数modLiXi(),可以将利率lixi修改为新值。 实例化两个不同的CK对象saver1和saver2,结余分别为2000.0和3000.0。将lixi设置为3%,计算一个月后和3个月后每个存款人的结余并打印新的结果。 首先定义储蓄类CK,它包含一个私有数据成员cunkuan,数据类型为double,一个静态数据成员年利率lixi,数据类型也为double;包含一个成员函数calLiXi()和一个静态成员函数modLiXi(),其中modLiXi()应含有一个表示要更改的年利率的新值的参数。 完善程序: #include class CK{ double cunkuan; public: ? //定义静态数据成员lixi CK(double c){?}//构造函数 void set(double x){?}//设置存款额 ? //定义静态成员函数modLiXi() void calLiXi(int m=1); };

实验8 多态性与虚函数

实验八多态性与虚函数 一、实验目的和要求 1.了解多态的概念; 2.了解虚函数的作用及使用方法; 3.了解静态关联和动态关联的概念和用法; 4.了解纯虚函数和抽象类的概念和用法 二、实验内容和结果 1.阅读下面的程序 1.1请写出程序的执行结果,并在上机时对照理解 class Vehicle {public: void run() const { cout << "run a vehicle. "<

airplane.run(); cout<<"(b) 用指向基类的指针访问成员函数: "<run(); vp=&airplane; vp‐>run(); } 1.2 如果将Vehicle 类的定义修改为虚函数,其余不变,请写出程序的执行结果,并在上机时对照理解 class Vehicle {public: virtual void run() const { cout << "run a vehicle. "<

C++友元习题

01.分析以下程序的执行结果 #include class Sample { int n; public: Sample(int i){n=i;} friend int add(Sample &s1,Sample &s2); }; int add(Sample &s1,Sample &s2) { return s1.n+s2.n; } void main() { Sample s1(10),s2(20); cout< class B; class A { int i; public: int set(B&); int get(){return i;} A(int x){i=x;} }; class B { int i; public: B(int x){i=x;} friend A;

int A::set(B &b) // 由于使用了类B的定义,故本函数的定义应放在类B定义之后 { return i=b.i; } void main() { A a(1); B b(2); cout< #include class student { char name[10]; int deg; public: student(char na[],int d) { strcpy(name,na); deg=d; } char *getname(){ return name;} friend int compare(student &s1,student &s2) { if(s1.deg>s2.deg) return 1; else if(s1.deg==s2.deg) return 0; else return -1;

网络实验-3个路由器的静态路由配置实验

计算机网络实验(4B) 实验名称:路由器的基本操作及静态路由配置实验 实验目的:了解路由器的基本结构,功能,使用环境以及基本参数的配置。 实验要求: 1.配置路由器接口的IP地址。 2.设置静态路由。 3. 测试静态路由:ping IP 地址; trace IP 地址 4.写出实验报告 实验准备知识: 一、实验环境的搭建: ?准备 PC 机 2 台,操作系统为 Windows XP ; ?准备Huawei S2501E 路由器 3 台; ?路由器串口线(2对) ?交叉线(或通过交换机的直连线)网线 2条; ? Console电缆2条。 步骤:del 删除各个路由器原有的路由表 ?第一步:设置Router1 [Quidway]SYSNAME R1 ?[R1] interface Ethernet 0 #设置其IP地址 ?[R1-Ethernet0] ip address 10.0.0.2 255.255.255.0 shutdown undo shutdown #激活此以太网口!!(对此口配置了IP地址后用此命令) #进入串口Serial0视图 ?[R1-Ethernet0] interface serial 0 #设置其IP地址

?[R1-Serial0] ip address 20.1.0.1 255.255.255.0 shutdown undo shutdown #激活此串口!!(对此口配置了IP地址后用此命令) #设置链路层协议为PPP ?[R1-Serial0] link-protocol ppp #进入系统视图 ?[R1-Serial0] quit #添加静态路由 ?[R1] ip route-static 40.1.0.0 255.255.255.0 20.1.0.2 preference 60 ##添加静态路由(R2的以太网接口) [R1] ip route-static 50.1.0.0 255.255.255.0 20.1.0.2 preference 60 #保存路由器设置 ?[R1] save #重启路由器 ?[R1] reboot ?第二步:设置Router2 [Quidway]SYSNAME R2 #进入以太网接口视图: ?[R2] interface Ethernet 0 #设置其IP地址 ?[R2-Ethernet0] ip address 50.1.0.2 255.255.255.0 shutdown undo shutdown #激活此以太网口!!! #进入串口Serial0视图 ?[R2-Ethernet0] interface serial 0 #设置其IP地址 ?[R2-Serial0] ip address 20.1.0.2 255.255.255.0 shutdown undo shutdown #激活此串口!!(对此口配置了IP地址后用此命令) #设置链路层协议为PPP ?[R2-Serial0] link-protocol ppp #进入系统视图 ?[R2-Serial0] quit #进入串口Serial1视图 ?[R2] interface serial 1 #设置其IP地址 ?[R2-Serial1] ip address 30.1.0.1 255.255.255.0 shutdown

静态成员函数一般情况下只能访问静态成员变量

静态成员函数一般情况下只能访问静态成员变量,因为不接受隐含的this指针。另外作为类的静态成员函数,不用声明对象,便可直接调用,例如类A的静态成员函数fun(); A::fun(); 1、主要用于封装全局变量和全局函数。以避免在文件作用域内包含带外部连接的数据。 例如全局变量:int path;int para1; 解决办法:设计一个全局类,并将这些全局名称声明为静态变量,并编写静态函数来调用这些变量。 class Global{ static int s_path; static int s_para; private: Global();//不实现,避免无意中的实例化 public: //manipulators static void setPath(int path){s_path = path;} static void setPara(int para){s_para = para;} //accessors static int getPath(){return s_path;} static int getPara(){return s_para;} } 2、对自由函数的封装 在.h文件的文件作用域内避免使用自由函数(运算符函数除外);在.c文件中避免使用带有外部连接的自由函数,因此可以使用静态成员函数进行处理。 例如:int getPara();int getPath();我们可以通过声明一个结构的静态方法代替: struct SysUtil{ static int getPath(); static int getPara(); }这样,唯一有冲突危险的就是出现类名SysUtil了。

static变量和static函数的各自的特点

static变量和static函数的各自的特点 static变量大致分为三种用法 一、用于局部变量中,成为静态局部变量. 静态局部变量有两个用法,记忆功能和全局生存期. 二、用于全局变量,主要作用是限制此全局变量被其他的文件调用. 三、用于类中的成员.表示这个成员是属于这个类但是不属于类中任意特定对象 static 声明的变量. 在C语言中有两方面的特征: 1、变量会被放在程序的全局存储区中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。 2、变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。 Tips: A.若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度; B.若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度; C.设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题; D.如果我们需要一个可重入的函数,那么,我们一定

要避免函数中使用static变量(这样的函数被称为:带“内部存储器”功能的的函数) E.函数中必须要使用static变量情况:比如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。 函数前加static使得函数成为静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件(所以又称内部函数)。使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名。 扩展分析:术语static有着不寻常的历史.起初,在C中引入关键字static是为了表示退出一个块后仍然存在的局部变量。随后,static在C中有了第二种含义:用来表示不能被其它文件访问的全局变量和函数。为了避免引入新的关键字,所以仍使用static关键字来表示这第二种含义。最后,C++重用了这个关键字,并赋予它与前面不同的第三种含义:表示属于一个类而不是属于此类的任何特定对象的变量和函数(与Java中此关键字的含义相同)。

静态路由配置实验报告记录

静态路由配置实验报告记录

————————————————————————————————作者:————————————————————————————————日期:

三峡大学计算机与信息学院标准实验报告(实验)课程名称计算机网络 三峡大学计算机与信息学院

实验报告 学生姓名:郑国安学号:2010114130 指导教师:马凯 实验地点:电气信息楼实验时间:2013.6.13 一、实验室名称: 二、实验项目名称:静态路由的配置 三、实验学时:2学时 四、实验原理: 路由器属于网络层设备,能够根据IP包头的信息,选择一条最佳路径,将数据包转发出去。实现不同网段的主机之间的互相访问。 路由器是根据路由表进行选路和转发的。而路由表里就是由一条条的路由信息组成。路由表的产生方式一般有3种: 直连路由给路由器接口配置一个IP地址,路由器自动产生本接口IP所在网段的路由信息。 静态路由在拓扑结构简单的网络中,网管员通过手工的方式配置本路由器未知网段的路由信息,从而实现不同网段之间的连接。 五、实验目的:掌握通过静态路由方式实现网络的连通性。 六、实验内容: 假设校园网通过1台路由器连接到校园外的另1台路由器上,现要在路由器上做适当配置,实现校园网内部主机与校园网外部主

机的相互通信。通过软件仿真,实现网络的互连互通,从而实现信息的共享和传递。 七、实验器材(设备、元器件): R2621XM(两台)、Serial DTE线缆(1条)、copper cross-over 线缆(2条)、PC(两台) 八、实验步骤: 打开Cisco Packet Tracer 软件,添加2台Generic路由器和2台Generic主机,用“自动选择连接类型”把设备连接起来,如下实验图,其中PC0、PC1为两台工作站主机,Router1、Router2为两台路由器。 然后按以下步骤完成配置: 步骤1. 在路由器Router1上配置接口的IP地址和串口上的时钟频率。 Router1(config)# Router1(config-if)# ip address 172.16.1.1 255.255.255.0 Router1(config-if)# no shutdown Router1(config)# interface serial 1/0

C++静态成员函数小结

C++静态成员函数小结 一静态数据成员 (1) 1.静态数据成员的定义 (1) 2.静态数据成员被类的所有对象所共享(包括该类派生类的对象) (2) 3.静态数据成员可以成为成员函数的可选参数(普通数据成员则不可以) (2) 4.静态数据成员的类型可以是所属类的类型(普通数据成员则不可以) (3) 5.静态数据成员的值在const成员函数中可以被合法的改变 (3) 二静态成员函数 (3) 1.静态成员函数的地址可用普通函数指针储存(普通成员函数地址需要用类成员函数 指针来储存) (4) 2.静态成员函数不可以调用类的非静态成员 (4) 3.静态成员函数不可以同时声明为virtual、const、volatile函数 (4) 类中的静态成员真是个让人爱恨交加的特性。我决定好好总结一下静态类成员的知识点,以便自己在以后面试中,在此类问题上不在被动。 静态类成员包括静态数据成员和静态函数成员两部分。 一静态数据成员 类体中的数据成员的声明前加上static关键字,该数据成员就成为了该类的静态数据成员。和其他数据成员一样,静态数据成员也遵守public/protected/private访问规则。同时,静态数据成员还具有以下特点: 1.静态数据成员的定义 静态数据成员实际上是类域中的全局变量。所以,静态数据成员的定义(初始化)不应该被放在头文件中。其定义方式与全局变量相同。举例如下: xxx.h文件 class base{ private: static const int _i;//声明,标准c++支持有序类型在类体中初始化,但vc6不支持。 }; xxx.cpp文件 const int base::_i=10;//定义(初始化)时不受private和protected访问限制. 注:不要试图在头文件中定义(初始化)静态数据成员。在大多数的情况下,这样做会引起重复定义这样的

c++多态性与虚函数习题

作业题 一、写出下列程序运行结果 1.#include using namespace std; class A { public: virtual void func( ) {cout<<”func in class A”< using namespace std; class A{ public: virtual ~A( ){ cout<<”A::~A( ) called “<

}; void fun(A *a) { delete a; } int main( ) { A *a=new B(10); fun(a); } 二、程序设计题 1有一个交通工具类vehicle,将它作为基类派生小车类car、卡车类truck和轮船类boat,定义这些类并定义一个虚函数用来显示各类信息。 5.2定义一个shape抽象类,派生出Rectangle类和Circle类,计算各派生类对象的面积Area( )。 5.5某学校对教师每月工资的计算公式如下:固定工资+课时补贴。教授的固定工资为5000元,每个课时补贴50元;副教授的固定工资为3000元,每个课时补贴30元;讲师的固定工资为2000元,每个课时补贴20元。给出教师抽象类及主函数,补充编写程序求若干教师的月工资。 #include using namespace std; class Teacher{ protected: double salary; int workhours; public: Teacher(int wh=0){workhours=wh;} virtual void cal_salary()=0; void print(){cout<cal_salary(); prof.print(); Vice_Prof vice_prof(250); pt=&vice_prof; pt->cal_salary(); vice_prof.print(); Lecture lecture(100); pt=&lecture; pt->cal_salary(); lecture.print (); return 0; }

C++中静态成员函数访问非静态成员变量

C++中静态成员函数访问非静态成员变量 这两天写一个简单的程序,由于程序运行占用cpu比较厉害,导致运行中界面窗口无法交互,因此想到了多线程,以前没有接触过mfc多线程,在网上看了两篇文章,觉得也不过如此,就开始动手写了,结果发现即使是看别人写很简单,自己动手也会出现很多问题,哪怕是看起来真的很简单的问题。 这里遇到的问题就是由于多线程的函数必须是static的,然后需要在里面调用non-static的函数,我就没有办法了,于是又开始网上找资料,下面就将这篇文章转贴过来,供大家学习思考:先看一个class class a { public: static FunctionA() { menber = 1; } private: int menber; } 编译上述代码,出错。原因很简单大家都知道,静态成员函数不能访问非静态成员,这是因为静态函数属于类而不是属于整个对象,静态函数中的 member可能都没有分配内存。静态成员函数没有隐含的this自变量。所以,它就无法访问自己类的非静态成员。(看过一篇很好的文章《浅析C++中的this指针》介绍这个方面的详细内容)那要想访问怎么办呢?地球人都知道只要将: int menber; //change the line above to: static int menber; 但是这个方法让我们不得不将static function内用到的成员变量都变成static的了,而且static 的成员还要显式初始化,有没有更好的方法?答案是肯定的。如下: class a { public: static FunctionA(a* _a) { a-> menber = 1; (window.cproArray = window.cproArray || []).push({ id: "u2280119" }); } private: int menber; } 前提是这个类要分配了内存空间。其实这里我做的就是将一个对象指针作为静态成员函数的“this”指针,意在模仿传递非静态成员函数里this变量。

实验五静态路由配置

南昌大学实验报告 学生姓名:学号:专业班级: 实验类型:□验证■综合□设计□创新实验日期:实验成绩: 实验五静态路由配置实训 一、实验目的 ●进一步掌握路由器配置命令的使用 ●熟悉静态路由与默认路由的配置命令 ●熟悉tracert路由跟踪命令 二、实验设备及条件 ●运行Windows操作系统计算机一台 ●Cisco 1840路由器两台,RJ-45转DB-9反接线一根,串口线一根 ●超级终端应用程序或Cisco Packet Tracer软件 三、实验原理 实训原理 路由器属于网络层设备,能够根据IP包头的信息,选择一条最佳路径,将数据包转发出去,以实现不 同网段的主机之间的互相访问。选择最佳路径的策略即路由算法是路由器的关键所在。 路由器的工作原理 为了完成路由选择工作,在路由器中保存着各种传输路径的相关数据——路由表(Routing Table), 供路由选择时使用。打个比方,路由表就像我们平时使用的地图一样,标识着各种路线,路由表中保存着 子网的标志信息、网上路由器的个数和下一个路由器的名字等内容。路由表可以是由系统管理员固定设置 好的,也可以由系统动态修改,可以由路由器自动调整,也可以由主机控制。 路由表的项目一般含有五个基本字段:目的地址、网络掩码、下一跳地址、接口、度量。在进行路由 选择时,路由器按照直接路由->特定主机路由->特定网络路由->默认路由的顺序讲IP包头与路由表项进行 匹配。 -直接路由项是指:该表项的“目的地址”所在网络与路由器直接相连。 -间接路由项是指:该表项的“目的地址”所在网络与路由器非直接相连。 -特定主机路由项是指:该表项的“目的地址”字段是某台特定主机的IP地址。 -特定网络路由项是指:该表项的“目的地址”字段是另一个网络的地址。 -默认路由(缺省路由)项是指:一种特殊的静态路由,当路由表中没有与数据包的目的地址匹配的项时,路由器做出的选择,该路由表表项的“目的地址”

静态成员和友元实验报告

[标准实验报告] 南昌航空大学实验报告 2011 年11月11 日 课程名称:面向对象程序设计B 实验名称:静态成员和友元 班级:10202327 姓名:吕潇同组人: 指导教师评定:签名: 一、实验目的 (1)学习静态成员的使用,理解静态成员的特殊用途。 (2)学习友元函数及友元类,领会友元类的作用。 二、实验内容(本次实验要完成的内容) 应用VC++6.0的编辑环境构造一个类Stack,设计一个整数链表类,实现栈操作。类中需有记录结点个数的数据成员(静态成员),要有判空操作。编制应用程序,取100次随机数(<1000),如果取到的随机数比前一个随机数大的话,入栈,然后逐个取出(即出栈过程)求其和。 用堆分配方法逐个产生满足条件(递增有序)的结点,插入栈中,每当出栈时,要及时将结点删除,求和工作放在类定义外(友元)。 注意:栈中最多会有100个元素,最少会有一个元素,这是由条件(递增有序)决定的。 具体说明如下: struct SNode{ int data; SNode *next; }; class Stack{ public: Stack(); ~Stack(); void Push(int e);//insert a data into stack int Pop();//delete a data from stack friend int GetSum(Stack &);//get sum of stack,friend function //friend class getsum;// get sum of stack,friend class,you can try it using friend class static int num;//static number private: SNode *head; };

静态函数 静态数据成员与静态成员函数 为什么虚函数必须是非静态成员函数 构造函数能为static吗

静态函数静态数据成员与静态成员函数为什么虚函数必须是非静态成员函数构造函数能为static吗? 2009-07-05 14:27 静态函数 用static声明的函数是静态函数。静态函数可以分为全局静态函数和类的静态成员函数。 Static关键字 在类中,用static声明的成员变量为静态成员变量,它为该类的公用变量,在第一次使用时被初始化,对于该类的所有对象来说,static成员变量只有一份。用static声明的方法是静态方法,在调用该方法时,不会将对象的引用传递给它,所以在static方法中不可访问非static的成员。 静态方法不再是针对于某个对象调用,所以不能访问非静态成员。 可以通过对象引用或类名(不需要实例化)访问静态成员 C++类静态数据成员与类静态成员函数 函数调用的结果不会访问或者修改任何对象(非static)数据成员,这样的成员声明为静态成员函数比较好。且如果static int func(....)不是出现在类中,则它不是一个静态成员函数,只是一个普通的全局函数,只不过由于static的限制,它只能在文件所在的编译单位内使用,不能在其它编译单位内使用。 静态成员函数的声明除了在类体的函数声明前加上关键字static,以及不能声明为const或者volatile之外,与非静态成员函数相同。出现在类体之外的函数定义不能制定关键字static。 静态成员函数没有this指针。 在没有讲述本章内容之前如果我们想要在一个范围内共享某一个数据,那么我们会设立全局对象,但面向对象的程序是由对象构成的,我们如何才能在类范围内共享数据呢? 这个问题便是本章的重点:声明为static的类成员或者成员函数便能在类的范围内共同享,我们把这样的成员称做静态成员和静态成员函数。 下面我们用几个实例来说明这个问题,类的成员需要保护,通常情况下为了不违背类的封装特性,我们是把类成员设置为protected(保护状态)的,但是我们为了简化代码,使要说明的问题更为直观,更容易理解,我们在此处都设置为public。 以下程序我们来做一个模拟访问的例子,在程序中,每建立一个对象我们设置的类静态成员变自动加一,代码如下: #include using namespace std;

实验6多态性与虚函数

[实验目的] 1、了解多态性的概念; 2、了解虚函数的用途及使用方法; 3、了解纯虚函数和抽象类的概念和用法。 [实验要求] 给出以下各实验内容的源程序代码,并把编译、运行过程中出现的问题以及解决方法填入实验报告中,按时上交。 [实验学时] 2学时。 [实验内容] 1、写一个程序,定义抽象基类Shape,由它派生出3个派生类:Circle(圆形)、Square(正方形)、Rectangle(矩形)。利用指针、虚函数printArea()分别输出以上三者的面积,3个图形的数据在定义对象时给定。 [源程序] #include using namespace std; class Shape { public: virtual float area()const=0; virtual void display()const=0; }; class Circle:public Shape { public: Circle(double a):r(a){} virtual float area()const{return 3.14*r*r;} virtual void display()const { cout<<"圆面积"<

class Rectangle:public Shape { public: Rectangle(double a,double b):l(a),w(b){} virtual float area()const{return l*w;} virtual void display()const { cout<<"矩形面积"<display(); m=m+p[i]->area(); }

实验4 静态成员与友元

3.2 实验与实践任务 3.2.1 实验名称静态成员和友元 3.2.2 实验目的 1.掌握静态成员的定义和使用。 2.掌握友元的定义和使用。 3.2.3 实验要求 1.调试程序要记录调试过程中出现的问题及解决办法; 2.编写程序要规范、正确,上机调试过程和结果要有记录,并注意调试程序集成环境的掌握及应用,不断积累编程及调试经验; 3.在编写程序时,要按照多文件结构来组织程序。 4.做完实验后给出本实验的实验报告,实验报告的内容包括实验目的、实验内容和结果分析。 3.2.4 实验内容 【P1】商店销售某一商品,商店每天公布统一的折扣(discount)。同时允许销售人员在销售是灵活掌握售价(price),在此基础上,对一次购10件以上者,还可以享受9.8折优惠。现在已知当天3名销售员的销售情况为: 销售员货号(num)销货件数(quantity)销货单价(price) 101 5 23.5 102 12 24.56 103 100 21.5 请编程序,计算出当日此商品的总销售款sum,以及每件商品的平均售价。要求用静态数据成员和静态成员函数 【P2】创建一个SavingsAccount类:用static(静态)数据成员包含每个存款人的annualInterestRate(年利率)。类的每个成员包含一个private数据成员savingsBalance,表示当前存款额。 提供一个calculateMonthlyInterest 成员函数,计算月利息,用savingsBalance乘以annualInterestRate除以12取得,并将当月月息加入savingsBalance。 提供一个静态成员函数modifyInterestRate,将静态annualInterestRate设置为新值。实例化两个不同的SavingsAccount对象saver1和saver2,余额分别为$2 000.00和$3 000.00 将annualInterestRate设置为3%,计算每个存款人的月息并打印出新的结果。 【P3】学校的人事部门保存了有关学生的部分数据(学号、姓名、年龄、住址),教务部门也保存了学生的另外一些数据(学号、姓名、性别、成绩),两个部门分别编写了本部门的学生数据管理程序,其中都用了Student作为类名。现在要求在全校的学生数据管理程序中调用这两个部门的学生数据,分别输出两种内容的学生数据。要求用标准C++编程,使用命名空间。 【P4】设计一个日期类Date,包含日期的年、月、日三个私有数据成员,编写一个友元函数,求两个日期之间相差的天数。 【P5】每一个学生有学号、姓名、一门课的成绩等基本信息。编写一个程序,用友元

相关主题
文本预览
相关文档 最新文档