c,,,类,静态函数模板

c,,,类,静态函数模板
c,,,类,静态函数模板

竭诚为您提供优质文档/双击可除c,,,类,静态函数模板

篇一:类模板的编译

类模板的编译

首先,c++标准中提到,一个编译单元[translationunit]是指一个.cpp文件以及它所include的所有.h文件,.h文件里的代码将会被扩展到包含它的.cpp文件里,然后编译器编译该.cpp文件为一个.obj文件,后者拥有

pe[portableexecutable,即windows可执行文件]文件格式,并且本身包含的就已经是二进制码,但是,不一定能够执行,因为并不保证其中一定有main函数。当编译器将一个工程里的所有.cpp文件以分离的方式编译完毕后,再由连接器(linker)进行连接成为一个.exe文件。

举个例子:

//---------------test.h-------------------//

voidf();//这里声明一个函数f

//---------------test.cpp--------------//

#include”test.h”

voidf()

{

//dosomething

}//这里实现出test.h中声明的f函数

//---------------main.cpp--------------//

#include”test.h”

intmain()

{

f();//调用f,f具有外部连接类型

}

在这个例子中,test.cpp和main.cpp各被编译成为不同的.obj文件[姑且命名为test.obj和main.obj],在main.cpp中,调用了f函数,然而当编译器编译main.cpp 时,它所仅仅知道的只是main.cpp中所包含的test.h文件中的一个关于voidf();的声明,所以,编译器将这里的f看作外部连接类型,即认为它的函数实现代码在另一个.obj文件中,本例也就是test.obj,也就是说,main.obj中实际没有关于f函数的哪怕一行二进制代码,而这些代码实际存在于test.cpp所编译成的test.obj中。在main.obj中对f 的调用只会生成一行call指令,像这样:callf[c++中这个名字当然是经过mangling[处理]过的]

在编译时,这个call指令显然是错误的,因为main.obj 中并无一行f的实现代码。那怎么办呢?这就是连接器的任

务,连接器负责在其它的.obj中[本例为test.obj]寻找f 的实现代码,找到以后将callf这个指令的调用地址换成实际的f的函数进入点地址。需要注意的是:连接器实际上将工程里的.obj“连接”成了一个.exe文件,而它最关键的任务就是上面说的,寻找一个外部连接符号在另一个.obj中的地址,然后替换原来的“虚假”地址。

这个过程如果说的更深入就是:

callf这行指令其实并不是这样的,它实际上是所谓的stub,也就是一个

jmp0x23423[这个地址可能是任意的,然而关键是这个地址上有一行

指令来进行真正的callf动作。也就是说,这个.obj文件里面所有对f的调用都jmp向同一个地址,在后者那儿才真正”call”f。这样做的好处就是连接器修改地址时只要对后者的callxxx地址作改动就行了。但是,连接器是如何找到f的实际地址的呢[在本例中这处于test.obj中],因为.obj于.exe的格式都是一样的,在这样的文件中有一个符号导入表和符号导出表[importtable和exporttable]其中将所有符号和它们的地址关联起来。这样连接器只要在test.obj的符号导出表中寻找符号f[当然c++对f作了mangling]的地址就行了,然后作一些偏移量处理后[因为是将两个.obj文件合并,当然地址会有一定的偏移,这个连接

器清楚]写入main.obj中的符号导入表中f所占有的那一项。这就是大概的过程。其中关键就是:

编译main.cpp时,编译器不知道f的实现,所有当碰

到对它的调用时只是给出一个指示,指示连接器应该为它寻找f的实现体。这也就是说main.obj中没有关于f的任何

一行二进制代码。

编译test.cpp时,编译器找到了f的实现。于是乎f

的实现[二进制代码]出现在test.obj里。

连接时,连接器在test.obj中找到f的实现代码[二进制]的地址[通过符号导出表]。然后将main.obj中悬而未决的callxxx地址改成f实际的地址。

完成。

然而,对于模板,你知道,模板函数的代码其实并不能直接编译成二

进制代码,其中要有一个“具现化”的过程。举个例子://----------main.cpp------//

template

voidf(tt)

{}

intmain()

{

//dosomething

f(10);//callf编译器在这里决定给f一个f的具现体//dootherthing

}

也就是说,如果你在main.cpp文件中没有调用过f,f 也就得不到具现,从而main.obj中也就没有关于f的任意一行二进制代码!!如果你这样调用了:

f(10);//f得以具现化出来

f(10.0);//f得以具现化出来

这样main.obj中也就有了f,f两个函数的二进制代码段。以此类推。

然而具现化要求编译器知道模板的定义,不是吗?

看下面的例子:[将模板和它的实现分离]

//-------------test.h----------------//

template

classa

{

public:

voidf();//这里只是个声明

};

//---------------test.cpp-------------//

#include”test.h”

template

voida::f()//模板的实现,但注意:不是具现

{

//dosomething

}

//---------------main.cpp---------------//

#include”test.h”

intmain()

{

aa;

a.f();//编译器在这里并不知道a::f的定义,因为它不在test.h里面

//于是编译器只好寄希望于连接器,希望它能够在其他.obj里面找到//a::f的实现体,在本例中就是test.obj,然而,后者中真有a::f的

篇二:c++标准库和标准模板库

c++标准库和标准模板库

c++强大的功能来源于其丰富的类库及库函数资源。c++标准库的内容总共在50个标准头文件中定义。在c++开发中,要尽可能地利用标准库完成。这样做的直接好处包括:(1)成本:已经作为标准提供,何苦再花费时间、人力重新开发呢;(2)质量:标准库的都是经过严格测试的,正确性有保证;(3)效率:关于人的效率已经体现在成本中了,关于代

码的执行效率要相信实现标准库的大牛们的水平;(4)良好的编程风格:采用行业中普遍的做法进行开发。

在c++程序设计课程中,尤其是作为第一门程序设计课程,我们注重了语法、语言的机制等方面的内容。程序设计能力的培养有个过程,跨过基本的原理性知识直接进入到工程中的普遍做法,由于跨度决定了其难度。再者,在掌握了基本原理的基础上,在认识标准库的问题上完全可以凭借实践,逐步地掌握。标准库的学习不需要认认真真地读书,需要的是在了解概貌的情况下,在实践中深入。这个任务就是要知道c++程序设计课程中不讲的,但对程序设计又很重要的这部分内容。至少我们要能先回答出“有什么”的问题。

一、c++标准库

c++标准库的内容分为10类,分别是:c1.语言支持;c2.输入/输出;c3.诊断;c4.一般工具;c5.字符串;c6.容器;c7.迭代器支持;c8.算法;c9.数值操作;c10.本地化。c1.标准库中与语言支持功能相关的头文件(11个)c2.支持流输入/输出的头文件(11个)

c3.与诊断功能相关的头文件(3个)

c5.支持字符串处理的头文件(6个)

c6.定义容器类的模板的头文件(8个)

c7.支持迭代器的头文件(1个)

c8.有关算法的头文件(3个)

c10.有关本地化的头文件(2个)

c++标准库的所有头文件

都没有扩展名。c++标准库以形式的标准头文件提供。

在形式标准的头文件中,与宏相关的名称在全局作用域中定义,其他名称在std命名空间中声明。在c++中还可以使用name.h形式的标准c库头文件名。在这10类头文件中,头文件分别在c5/c8/c9中出现了。

二、标准模板库stl简介

stl(standardtemplatelibrary,标准模板库)是惠普实验室开发的一系列软件的统称。现然主要出现在c++中,但在被引入c++之前该技术就已经存在了很长的一段时间。

stl的代码从广义上讲分为三类:algorithm(算法)、container(容器)和iterator(迭代器),几乎所有的代码都采用了模板类和模版函数的方式,这相比于传统的由函数和类组成的库来说提供了更好的代码重用机会。在c++标准中,stl被组织为下面的13个头文件:、、、、、、、、、、、和。

1、算法

函数库对数据类型的选择和对其可重用性起着至关重要的作用。举例来说,一个求方根的函数,在使用浮点数作为其参数类型的情况下的可重用性肯定比使用整型作为它的参数类性要高。而c++通过模板的机制允许推迟对某些类型的选择,直到真正想使用模板或者说对模板进行特化的时

C++函数模板详解

C++函数模板详解 经常有碰到函数模块的应用,很多书上也只是略有小讲一下,今天又狂碰到函数模块,无奈特地找来C++编程经典<>翻阅一遍,终于有所全面了解..... C++函数模块基础知识: 一. 问题: 强类型语言要求我们为所有希望比较的类型都实现一个实例 int min( int a, int b ) { return a < b ? a : b; } double min( double a, double b ) { return a < b ? a : b; } 有一种方法可替代为每个min()实例都显式定义一个函数的方法这种方法很有吸引力但是也很危险.那就是用预处理器的宏扩展设施例如 :#define min(a,b) ((a) < (b) ? (a) : (b)) 在复杂调用的情况下,它的行为是不可预期的,这是因为它的两个参数值都被计算两次.一次是在a 和b 的测试中另一次是在宏的返回值被计算期间. #include #define min(a,b) ((a) < (b) ? (a) : (b)) const int size = 10; int ia[size]; int main() { int elem_cnt = 0; int *p = &ia[0]; // 计数数组元素的个数 while ( min(p++,&ia[size]) != &ia[size] ) ++elem_cnt; cout << "elem_cnt : " << elem_cnt << "\texpecting: " << size << endl; return 0; } 执行该程序的结果是下面不正确的计算结果: elem_cnt : 5 expecting: 10

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 <

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

实验八静态数据成员和静态函数成员 任务一: 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); };

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

静态成员函数一般情况下只能访问静态成员变量,因为不接受隐含的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了。

第 6 章(1)━━函数模板、类模板

C++程序设计 第6章(1) ━━函数模板、类模板

主要内容 ●关于模板 ●函数模板的定义 ●函数模板实例化 ●关于类模板 ●类模板的定义 ●类模板实例化 ●顺序表类模板的定义

关于模板 关于模版: ①为提高程序的通用性,必须使其代码不受数据类型的限制,即建立与数据类型无关 的通用函数或通用类,方法是将其中的数据类型参数化,在函数或类的定义中引入数据类型参数。 ②模板是函数或类的通用样板,当函数或类需要处理多种不同类型数据时,可通过模 板来创建具有通用功能的函数或类,即函数模板或类模板,以达到通用的目的。③由于一个函数模板可以支持多个具有不同数据类型形参的函数,从而简化了重载函 数的设计。 ④C++国际标准ISO 14882 将模板正式引入标准库,以模板类取代传统的C++类。 ⑤程序中的软件模块由模板构造,即函数模板实例化产生相应的模板函数,类模板实 例化产生相应的模板类,这种程序设计类型称为参数化程序设计。

函数模板的定义 函数模板的定义: template <模板形参列表> 返回值类型函数名(函数形参列表){ 函数体} ①模板形参有两种:类型参数、常规参数 ②类型参数:由typename或class后加一个标 识符构成,该标识符用在紧跟其后的函数中代表一种潜在的数据类型。 ③常规参数:由类型符( 如int、float ) 后加一个标识符构成,该标识符用在紧跟其后的函数中代表一个潜在的常量。 ④模板形参格式:typename 形参名 class 形参名 数据类型形参名①函数的返回值类型、形参类型以及函数体中, 均可使用前面模板形参表中给出的类型参数来代表某种潜在的数据类型,该类型参数代表的具体类型只有在调用函数时根据给出的模板实参才能确定! ②在函数体中,还可使用前面模板形参表中给 出的常规参数来代表一个潜在的常量,该常规参数代表的具体值只有在调用函数时根据给出的模板实参才能确定!因此其对应的模板实参必须是常量表达式。

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++中静态成员函数访问非静态成员变量

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变量。

泛微E-COLOGY显示模板函数公式整理

显示模板函数公式整理【初稿】 注意 请先详细阅读《流程表单设计器使用手册》一、数学函数

2、使用实例 1) ABS A1=ABS(B1*B2),B1=-10,B2=3,则A1=30 2) AVERAGE A1=AVERAGE(B1:B5),B1=5,B2=5,B3=-5,B4=5,B5=5,则A1=3 3)COS COS(数值),数值为弧度 4)EXP A1=EXP(4),则A1=54.59815 5)INT A1=(B1+B2),B1=10.64,B2=20.55,则A1=31 6)LN A1=LN(10),则A1=2.302585 7)LOG10 A1=LOG10(100),则A1=2 8) MAX A1=MAX(B000:E000),B2=15,C2=23,D2=12,E2=37,则A1=37 9)MIN A1=MIN(B000:B4),B2=12,B3=5,B4,则A1=5 10)MOD A1=MOD((MAX(B000:B5)+AVERAGE(C1:C5)),MIN(D1:D5)),B2=15,B3=25 B4=30,C1=20,C2=20,C3=30,C4=10,C5=40,D1=20,D2=15,D3=10,D4=30,D5=20,则A1=4 11)PI A1=PI(),则A1=3.14 12)ROUND A1=ROUND(15.228542,3),则A1=15.229 13)SIN SIN(数值),数值为弧度 14)SQRT A1=SQRT(100),则A1=10 15)SUM A5=SUM(B00:B0),B4=2,B3=4,B2=6,B1=数量,则A5=12 16) SUM_USERVAL 对单元区域中用户自定义数值相同的单元进行求和 17) SUM_USERVAL_DOWN 从上到下对单元区域中的单元用户自定义数值相同的单元进行求和,用户自定义数值不相同后不再计算 18) SUM_USERVAL_UP 从下到上对单元区域中的单元用户自定义数值相同的单元进行求和,用户自定义数值不相同后不再计算

静态函数 静态数据成员与静态成员函数 为什么虚函数必须是非静态成员函数 构造函数能为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;

在C语言中实现模板函数的方法

各种用C 语言实现的模板可能在使用形式上有所不同。现以一个求和函数Sum 为例,用C++ Template 可写如下: template R Sum(const T *array, int n) { R sum = 0; for (int i = 0 ; i < n ; ++i) sum += i; return sum; } 如果不是内置类型,该模板隐式地需要有R R::operator+=(T)运算符可用。 1. 使用函数指针作为Functor 替换者 Typedef struct tagAddClass { Void (*add)(char* r1, const char* r2); Int elemSize; Char sum[MAX_ELEM_SIZE]; } AddClass; void Sum(AddClass* self, const char* array, int n) { for (int i = 0 ; i < n ; ++i) self->add(self->sum, array + i*self->elemSize); } 使用时:

….. V oid AddInt(char* r1, const char* r2) { *(long*)r1 += *(int*)r2; } AddClass addClass = {AddInt, 2, 0 }; Int array[100]; Read(array); Sum(&addClass, array, 100); ….. 2. 用宏作为Functor的替换者 #define GenSumFun(SumFunName, Add, RetType, ElemType) \ RetType SumFunName (const ElemType *array, int n) \ { \ RetType sum = 0; \ for (int i = 0 ; i < n ; ++i) \ Add(sum, i); \ return sum; \ } 使用时: #define AddInt(x, y) ((x) += (y))

用函数模版求最大值

#include #include using namespace std; template//*定义一个模版*// T max(T array[],int k) { int max=0,i; for (i=1;iarray[max]) max=i; return array[max]; } int main() { int n,a[100]={0},choice,i; float b[100]; string c[100];//* 定义字符串*// cout<<"Please choose the data type you want to compare: 1. IntCom 2.FloatCom 3.StringCom 0.Exit"<>choice; switch(choice) { case 1: cout<<"Please input the number of array :"<>n; cout<<"Please input "<>a[i]; cout<<"The bigest number is "<>n; cout<<"Please input "<>b[i]; cout<<"The bigest number is "<>n; cout<<"Please input "<

C++教程第07章 类与对象-5 类的静态成员及常量

7章类与对象 7.1 类和对象(定义及使用)初步 7.2成员函数的重载 7.3 对象的初始化、构造函数与析构函数 7. 4 类的定义及其使用 7. 5 类的静态成员及常量成员 7.5.1静态成员 7.5.1.1静态成员数据 1.静态成员数据的定义,与静态类型的变量的定义方式一样,要在成员数据的定义之前加关键字static。 2.静态成员数据必须有确定的值,但由于在类的定义中不能对成员数据直接进行初始化,故必须在类定义的外部对静态成员数据再声明一次,并进行初始化,此时,前面不需要加关键字static。同时为了保持静态成员数据取值的一致性,一般在类的构造函数中不给静态成员数据设置初值。对静态成员数据初始化的顺序为它们在类体外声明的顺序. 3.在同一个程序中,当一个类有多个对象时,则这些对象中的静态成员数据都共享同一个存储空间,即在定义类时,就为静态成员数据分配存储单元,以后创建该类的对象时,将不再为该静态成员数据分配存储单元,也不会对该静态成员数据初始化。 静态成员数据初始化格式: <类型><类名> ::<静态成员数据> = <数值> ; 4.类的静态成员数据具有全局变量的某些特征,比如在程序开始运行时就为静态成员数据分配存储空间,但它只有类的作用域。即在执行main()之前,首先对静态成员数据和全局变量分配存储空间并进行初始化,当整个程序结束时才撤消静态成员数据和全局变量。5.静态成员数据也可以分为公有的、私有的和受保护的静态成员。 对公有静态成员,即可以通过类的对象进行访问,也可以通过类名直接访问(这是静态成员数据与一般成员数据的另一个区别)。格式: <类名>::<静态成员数据> 私有的和保护的静态成员数据则只能被该类的公有成员函数访问。 6.值得注意的是,在创建任何对象之前,类的静态成员数据已经存在并可以引. 7.静态成员数据也可以是用户自定义类型的数据。 7.5.1.2静态成员函数 1.定义静态成员函数时,只要在成员函数名前用关键字static修饰即可。 2.静态成员函数属于整个类,它是由该类的所有对象所共享的成员函数,它不属于某个对象。因此它不含有隐含的*this指针参数,故它不能像普通成员函数那样直接访问对象中的非静态的成员(成员函数和成员数据),即 静态成员函数只能访问所在类的静态的成员(成员函数和成员数据)、全局变量、外部函数等。(因为它们不属于任一个特定对象)。

C++编程之函数模板

C++编程之函数模板 1、函数之模版出现 在调换两个数值之间的函数写法上,由于有int、float、double等不同的数据类型,如下例:[cpp]view plain copy 1.void swapValues(int& num1, int& num2 ) 2.{ 3.int temp; 4. temp = num1; 5. num1 = num2; 6. num2 = temp; 7.} 上例只能适合于int 类型的变量,假如要调用double类型的两个数调换,又要重写上面的函数(把上面int 的位置全改为double)。可以达到目的,但不高效。我们需要一种能交换各种数据类型变量的函数定义,它的表示方法如下所示: [cpp]view plain copy 1.void swapValues( TypeData& var1, TypeData& var2) 2.{ 3. TypeData temp; 4. temp = var1; 5. var1 = var2; 6. var2 = temp; 7.} 在C++语言中,上述函数定义方式是可行的。我们可以定义一个适用于各种数据类型变量的函数。 2、函数模版语法 模版定义和函数声明以如下方式:

template// class 可以用typename关键字,实际上标准模版就是typename,只是大家习惯class 通常称为模版前缀,它告诉编译器函数定义或函数声明是一个模版,T表示一个类型参数。 3、函数模版之示例 //demo.h [cpp]view plain copy 1.template 2.void swapValues(T& var1,T& var2) 3.{ 4. T temp; 5. 6. temp = var1; 7. var1 = var2; 8. var2 = temp; 9.} //main.cpp [cpp]view plain copy 1.#include 2.#include"demo.h" 3. https://www.360docs.net/doc/e44932659.html,ing namespace std; 5. 6.int main() 7.{ 8.int num1 = 1,num2 = 2; 9.char ch1 = 'A', ch2 = 'B'; 10. 11. cout<<"Original integer values are " 12. <

matlab的M-文件 S-函数的标准模板

function [sys,x0,str,ts] = sfuntmpl(t,x,u,flag) % SFUNTMPL 是M-文件S函数模板 % 通过剪裁,用户可以生成自己的S函数,不过一定要重新命名 % 利用S函数可以生成连续、离散混合系统等,实现任何模块的功能% % M-文件S函数的语法为: % [SYS,X0,STR,TS] = SFUNC(T,X,U,FLAG,P1,...,Pn) % % 参数含义: % t是当前时间 % x是S函数相应的状态向量 % u是模块的输入 % flag是所要执行的任务 % % FLAG 结果功能 % ----- ------ -------------------------------------------- % 0 [SIZES,X0,STR,TS] 模块初始化 % 1 DX 计算模块导数 % 2 DS 更新模块离散状态 % 3 Y 计算模块输出 % 4 TNEXT 计算下一个采样时间点 % 9 [] 结束仿真 % % % 用户切勿改动输出参数的顺序、名称和数目

% 输入参数的数目不能小于1,这四个参数的名称和排列顺序不能改动 % 用户可以根据自己的要求添加额外的参数,位置依次为第5,6,7,8,9等。 % S函数的flag参数是一个标记变量,具有6个不同值,分别为0,1,2,3,4,9 % flag的6个值分别指向6个不同的子函数 % flag所指向的子函数也成为回调方法(Callback Methods) switch flag, %初始化,调用“模块初始化”子程序% case 0, [sys,x0,str,ts]=mdlInitializeSizes; %连续状态变量计算,调用“计算模块导数”子函数% case 1, sys=mdlDerivatives(t,x,u); %更新,调用“更新模块离散状态”子函数% case 2, sys=mdlUpdate(t,x,u); %输出,调用“计算模块输出”子函数% case 3, sys=mdlOutputs(t,x,u); %计算下一时刻采样点,调用“计算下一个采样时刻点”子函数% case 4, sys=mdlGetTimeOfNextVarHit(t,x,u); %结束,调用“结束仿真”子函数% case 9, sys=mdlTerminate(t,x,u); %其他的flag% otherwise DAStudio.error('Simulink:blocks:unhandledFlag', num2str(flag)); end % end sfuntmpl

实验4 含有类的静态成员与类的友元的C++程序设计

实验4 含有类的静态成员与类的友元的C++程序设计 专业:计算机科学与技术班级:10计本1班学号:姓名: 实验地点:B102实验时间:2011/11/1 指导教师:李佐勇 一、实验目的 1.理解类的静态成员解决共享问题的机制; 2.掌握类的静态数据成员与静态函数成员的实现方法; 3.理解利用友元关系实现数据共享的机制,掌握类的友元函数以及友元类的实现方法; 4.学习多文件结构在C++程序中的使用。 二、实验环境 一台PC机,Windows XP操作系统,Visual C++ 6.0开发环境。 三、实验内容 1.设计一个解决王婆卖瓜问题的程序。王婆卖瓜,每卖一个瓜,需记录该瓜的重量,还要记录所卖出的总重量和总个数,同时还允许退瓜。设计一个具有静态数据、函数成员的watermelon类。 实现提示:西瓜类有3个数据成员:重量weight、总重量total_weight以及总个数total_number。因为不论西瓜是否卖出,总重量total_weight和总个数total_number这两个数据总是要保留的,且这两个数据与单个的西瓜无关联,因此这两个数据要申明为静态数据成员。成员函数:卖瓜用构造函数模拟,退瓜用析构函数模拟,瓜重用disp成员函数给出屏幕提示。为了用不与特定对象相联系的静态成员函数来访问静态数据,还需要定义一个显示总重量和总个数的静态成员函数total_disp。 2.设计一个程序,其中有3个类,即CBank、BBank和GBank,分别为中国银行类、工商银行类和农业银行类。每个类都包含一个私有数据balance,用于存放储户在该行的存款数,另有一个友元函数total用于计算储户在这3家银行中的总存款数。 3. 设计一个程序,其中有2个类,Point类为点类,包含2个私有数据x和y,表示点的坐标,line类为直线类,包含3个私有数据a、b和c,表示直线方程ax+by+c=0。另有一个友元函数dist,用于计算一个点到直线的距离。点与直线之间的距离计算公式如下: 2 2b a c by ax d ++ + = 要求: ①将Point与Line类的定义放在头文件head.h中; ②将Point与Line类的实现部分放在PL.cpp中; ③主函数(类的使用)文件定义为:Lab04_3.cpp。 四、实验记录 1.#include using namespace std; class watermelon { public: watermelon(double w){ weight=w;

C 类的静态成员详细讲解

在C++中,静态成员是属于整个类的而不是某个对象,静态成员变量只存储一份供所有对象共用。所以在所有对象中都可以共享它。使用静态成员变量实现多个对象之间的数据共享不会破坏隐藏的原则,保证了安全性还可以节省内存。 静态成员的定义或声明要加个关键static。静态成员可以通过双冒号来使用即<类名>::<静态成员名>。 在C++中类的静态成员变量和静态成员函数是个容易出错的地方,本文先通过几个例子来总结静态成员变量和成员函数使用规则,再给出一个实例来加深印象。希望阅读本文可以使读者对类的静态成员变量和成员函数有更为深刻的认识。 第一个例子,通过类名调用静态成员函数和非静态成员函数 [cpp]view plaincopyprint? 1.class Point 2.{ 3.public: 4.void init() 5.{ 6.} 7.static void output() 8.{ 9.} 10.}; 11.void main() 12.{ 13.Point::init(); 14.Point::output(); 15.} 编译出错:error C2352:'Point::init':illegal call of non-static member function 结论1:不能通过类名来调用类的非静态成员函数。

第二个例子,通过类的对象调用静态成员函数和非静态成员函数将上例的main()改为: [cpp]view plaincopyprint? 1.void main() 2.{ 3.Point pt; 4.pt.init(); 5.pt.output(); 6.} 编译通过。 结论2:类的对象可以使用静态成员函数和非静态成员函数。 第三个例子,在类的静态成员函数中使用类的非静态成员[cpp]view plaincopyprint? 1.#include 2.class Point 3.{ 4.public: 5.void init() 6.{ 7.} 8.static void output() 9.{ 10.printf("%d\n",m_x); 11.} 12.private: 13.int m_x; 14.}; 15.void main() 16.{ 17.Point pt;

实验四类与对象(静态数据成员)

实验四类与对象(静态成员) 一、实验目的与要求 1.掌握类的定义,成员函数的定义; 2.掌握对象的初始化及应用; 3.掌握构造函数的使用; 4.掌握析构函数的使用; 5.掌握静态的使用; 二、实验内容 1.设计一个学生类Student,它要求有以下面成员: 私有数据成员: 注册号Registration,姓名Name、数学成绩Math、英语成绩English、高级程序设计成绩Programming; 静态数据信息学生人数Count; 具有的公有的函数成员: (1)求三门课总成绩的函数Sum(); (2)求三门课平均成绩的函数Average(); (3)显示学生数据信息的函数Print(); (4)获取学生注册号的函数Get_reg_num(); (5)设置学生数据信息的函数Set_stu_inf(); (6)静态的获取学生人数函数Get_coutnt(); (7)构造函数; (8)析构函数. 为了统一格式,也方便同学们更有针对性的实现 Student类的声明为: //Student.h #include using namespace std; class Student { private: int Registration; char Name[20];

int Math; int English; int Programming; static int Count; public: Student(int ,char[],int,int,int); Student(Student &); ~Student(); int Sum(); double Average(); void Print(); int Get_reg_num(); void Set_stu_inf(int,char[],int ,int ,int); static int Get_count(); }; //shiyan4_1.cpp #include"Student.h" //对静态数据成员进行初始化,补充代码 //(1) int main() { //1.输出当前的学生数,补充代码 cout<<"当前的学生数:"<

C++模板定义

C+=模板定义 1、模板的概念: 在C++中,模板是泛型编程的基础。模板是创建类或函数的蓝图或公式。 2、定义函数模板: 模板定义以template关键字开始,后接模板形参表(用<>括起来),多个模板形参用逗号隔开。 模板形参的名字没有实际意义。 1)模板形参表:模型形参可以是表示类型的类型形参,也可以是表示常量表达式的非类型形参。模板形参表不能为空。 2)使用模板函数:使用时,编译器会确定绑定到模板形参的模板实参类型。编译器确定用实际类型代替每个类型形参,用值代替每个非类型形参。 3)inline函数模板:如,template T max(const T&, const T&); 模板函数定义和使用示例: #include using std::cout; using std::endl; //定义模板函数 template int compare(const T &v1, const T &v2) { if(v1,其余部分与类的声明基本一致。 类模板可以定义数据成员、函数成员和类型成员,构造函数和析构函数等。也可以使用标号控制对成员的访问。 在类和类的成员中,可以使用模板形参作为类型或值的占位符,在使用类时再提供那些类型或值。 类模板示例:

C#静态类和静态类成员详解

C#静态类和静态类成员详解 C#静态类和静态类成员用于创建无需创建类的实例就能够访问的数据和函数。静态类成员可用于分离独立于任何对象标识的数据和行为:无论对象发生什么更改,这些数据和函数都不会随之变化。当类中没有依赖对象标识的数据或行为时,就可以使用静态类。 让我们来看看静态类: 类可以声明为static的,以指示它仅包含静态成员。不能使用new 关键字创建静态类的实例。静态类在加载包含该类的程序或命名空间时由.NET Framework 公共语言运行库(CLR) 自动加载。 使用静态类来包含不与特定对象关联的方法。例如,创建一组不操作实例数据并且不与代码中的特定对象关联的方法是很常见的要求。您应该使用静态类来包含那些方法。 静态类的主要功能如下: 1、它们仅包含静态成员。 2、它们不能被实例化。 3、它们是密封的。 4、它们不能包含实例构造函数(C# 编程指南)。 因此创建静态类与创建仅包含静态成员和私有构造函数的类大致一样。私有构造函数阻止类被实例化。 使用静态类的优点在于,编译器能够执行检查以确保不致偶然地添加实例成员。编译器将保证不会创建此类的实利。 静态类是密封的,因此不可被继承。静态类不能包含构造函数,但仍可声明静态构造函数以分配初始值或设置某个静态状态。 何时使用静态类 假设有一个类CompanyInfo,它包含用于获取有关公司名称和地址信息的下列方法。 1class CompanyInfo 2 3{ 4 5public string GetCompanyName() { return "CompanyName"; } 6 7public string GetCompanyAddress() { return "CompanyAddress"; } 8 9//... 10 11} 不需要将这些方法附加到该类的具体实例。因此,您可以将它声明为静态类,而不是创建此类的不必要实例,如下所示: 12static class CompanyInfo 13 14{ 15 16public static string GetCompanyName() { 17return "CompanyName"; }

相关文档
最新文档