C++基本概念(内联,模板,函数)

1、inline function

      嵌入到主调函数中的函数称为内置函数(inline function),又称内嵌函数,或内联函数。指定内置函数,只需在函数首行的左端加一个关键字inline即可。可以在声明函数和定义函数时同时写inline,也可以只在其中一处声明inline,效果相同。内置函数中不能包括复杂的控制语句,如循环语句和switch语句,一般少于5句。 对函数作inline声明,只是对编译系统提出的一个建议,编译系统会根据具体情况决定是否这样做。归纳起来,只有那些规模较小而又被频繁调用的简单函数,才适合于声明为inline函数。

2、function overloading 

       C++允许用同一函数名定义多个函数,这些函数的参数个数和参数类型不同。重载函数除了允许参数类型不同以外,还允许参数的个数不同。参数的个数和类型可以都不同。但不能只有函数的类型不同而参数的个数和类型相同,重载函数的参数个数、参数类型或参数顺序3者中必须至少有一种不同,函数返回值类型可以相同也可以不同。

3、function template

       所谓函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表。这个通用函数就称为函数模板。

Template <classs 类型参数表>

返回类型 函数名(函数模型形参表)

函数体

其中,class也可用typename代替:

template < typename T>  或  template <class T>

#include "iostream"

using namespace std;

template <typename T>

T abs(T x)

{

return x<0? -x:x;

}

int main()

{

int n=5;

double d=-5.5;

cout<<abs(n)<<endl;

cout<<abs(d)<<endl;

return 1;

}

以下为类模板(class template)定义:

Template <模板形参表>

Class 类名

 类模板体定义;

};

如template <class T>

Template <class T,int element>

模板类 <模板参数表> 对象名1,....对象名n。

如果模板类的成员函数在类外实现,则必须是模板函数。如:

template<class T>

T& Array<T>::operator[](int index) {

  return A[index];

Classname<int,double>obj1(86,175.3);

#include "iostream"

using namespace std;

template <class Type1,class Type2>

 class myclass

 {

private:

 Type1 i;

 Type2 j;

public:

 myclass(Type1 a,Type2 b)

 {

 i=a;

 j=b;

 }

 void show()

 {

 cout<<i<<" "<<j<<endl;

 }

 };

int main()

{

myclass<int,double>obj1(86,175.2);

myclass<char,char*>obj2('m',"Perfect");

obj1.show();

obj2.show();

return 1;

}

Template <class T>

Class Store

{...

Void PutElement(T x);

...}

void Store<T>::PutElement(T x);

     可以看到,用函数模板比函数重载更方便,程序更简洁。但应注意它只适用于函数的参数个数相同而类型不同,且函数体相同的情况,如果参数的个数不同,则不能用函数模板。

       由于类模板包含类型参数,因此又称为参数化的类。如果说类是对象的抽象,对象是类的实例,则类模板是类的抽象,类是类模板的实例。利用类模板可以建立含各种数据类型的类。

       归纳以上的介绍,可以这样声明和使用类模板: 

(1) 先写出一个实际的类。由于其语义明确,含义清楚,一般不会出错。

(2) 将此类中准备改变的类型名(如int要改变为float或char)改用一个自己指定的虚拟类型名(如上例中的numtype)。

(3) 在类声明前面加入一行,格式为 

template<class 虚拟类型参数>,如

template<class numtype>                //注意本行末尾无分号

class Compare                          

{…};                                   //类体

(4) 用类模板定义对象时用以下形式:

类模板名<实际类型名>  对象名;

类模板名<实际类型名>  对象名(实参表列);

Compare<int> cmp;

Compare<int> cmp(3,7);

(5) 如果在类模板外定义成员函数,应写成函数模板形式: 

template<class 虚拟类型参数>

函数类型 类模板名<虚拟类型参数>∷成员函数名(函数形参表列) {…}

template<class numtype>

numtype Compare<numtype>∷max( )

{{return (x>y)?x:y;}

说明: 

(1) 类模板的类型参数可以有一个或多个,每个类型前面都必须加class,如

template<class T1,class T2>

class someclass

{…};

在定义对象时分别代入实际的类型名,如

someclass<int,double> obj;

(2) 和使用类一样,使用类模板时要注意其作用域,只能在其有效作用域内用它定义对象。

(3) 模板可以有层次,一个类模板可以作为基类,派生出派生模板类。

4、有默认参数的函数

如有一函数声明(定义中)有float area(float r=6.5);//指定r的默认值为6.5

实参与形参的结合是从左至右顺序进行的。因此指定默认值的参数必须放在形参表列中的最右端,否则出错。

一个函数不能既作为重载函数,又作为有默认参数的函数。因为当调用函数时如果少写一个参数,系统无法判定是利用重载函数还是利用默认参数的函数,出现二义性,系统无法执行

5、内部函数和外部函数

     如果一个函数只能被本文件中其他函数所调用,它称为内部函数。在定义内部函数时,在函数名和函数类型的前面加static。函数首部的一般格式为

static 类型标识符 函数名(形参表)

如static int fun(int a,int b)内部函数又称静态(static)函数。

      在定义函数时,如果在函数首部的最左端冠以关键字extern,则表示此函数是外部函数,可供其他文件调用。如函数首部可以写为extern int fun (int a, int b)

这样,函数fun就可以为其他文件调用。如果在定义函数时省略extern,则默认为外部函数。在需要调用此函数的文件中,用extern声明所用的函数是外部函数。

6、函数原型、预处理

用函数原型能够把函数的作用域扩展到定义该函数的文件之外(不必使用extern)。只要在使用该函数的每一个文件中包含该函数的函数原型即可。函数原型通知编译系统:该函数在本文件中稍后定义,或在另一文件中定义。利用函数原型扩展函数作用域最常见的例子是#include命令的应用。

预处理命令是C++统一规定的,但是它不是C++语言本身的组成部分,不能直接对它们进行编译。为了与一般C++语句相区别,这些命令以符号“#”开头,而且末尾不包含分号。

C++提供的预处理功能主要有以下3种:

(1)  宏定义

(2)  文件包含

头文件是源文件之间的接口,新的C++标准库中的头文件一般不再包括后缀.H。

(3) 条件编译

但是有时希望程序中某一部分内容只在满足一定条件时才进行编译,也就是指定对程序中的一部分内容进行编译的条件。如果不满足这个条件,就不编译这部分内容。这就是“条件编译”。

A] 

#ifdef 标识符

程序段1

#else

程序段2

#endif

B]

#if 表达式

       程序段1

#else

       程序段2

#endif

发布了208 篇原创文章 · 获赞 30 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/hopegrace/article/details/104250954
今日推荐