C++ 函数的高级特性 20131002

C++函数增加了重载(override), inline, const, virtual四种机制,重载和内联机制既可以用于全局函数,也可以用于类的成员函数。const和virtual机制只是可以用于成员函数。

1.函数重载的概念

将功能和语义相似的几个函数使用同一个函数名字,便于记忆,同时类的构造函数确实需要使用到重载,但是C++的构造函数只能有一个名字,只能使用重载来实现。

虽然在语言层面上是相同的函数名称,但是在最终的二进制层面上是不允许出现同名函数的,因为所有的函数最终都将转换成一个等效的全局函数,调用语句也会作相应的转换。如何将他们区分开来:根据函数的返回值和参数列表。但是一般不使用返回值实现多态,只是根据参数的列表。编译器使用Name-Mapping技术重命名机制。

不要使用默认的隐式转换机制匹配重载函数:

void output(int x){

cout << "output int " << x<< endl;

}

void output(float x){

cout << "output float " << x << endl;

}

int main()

{

output(1);

output(0.5);// error 编译错误

return 0;

}

2.成员函数的重载(overloading)、覆盖(override)和隐藏

重载特征

相同的作用域;函数名字相同;参数类型、顺序、数目不同;virtual关键字可有可无

覆盖的特征

不同的作用域;函数名称相同;参数类表完全相同;基函数中必须是virtual关键字修饰的函数。同时虚函数的覆盖有两种方式:一个是完全重写,一种是扩展,扩展就是先调用基类的虚函数,在实现自己新增加的功能。

隐藏规则

C++中有隐藏的规则使问题的复杂性陡然增加。这里的隐藏就是指派生类的成员函数遮蔽了和他同名的基类成员函数:

派生类的函数和基类中的函数同名,但是参数列表有所差异,此时无论是否有virtual关键字,基类的函数在派生类中将被隐藏,而不是重载,也不是多态。

派生类的行数和基类的函数同名,参数列表也相同,但是基类函数中没有使用关键字virtual关键字修饰。此时基类的函数在派生类中将被隐藏,但不是覆盖。

有时候把它们称为“跨越类边界的重载”。

class Base{

public:

virtual void f(float x){

cout << "Base::f(float)" << endl;

}

void g(float x){

cout <<"Base::g(float)" << x << endl;

}

void h(float x){

cout << "Base::h(float)" << x <<endl;

}

};

class Derived:public Base{

public:

virtual void f(float x){

cout << "Derived::f(float)" << endl;

}

virtual void f(int x){

cout << "derived::f(int)" << endl;

}

void g(int x){

cout << "derived::g(int)" << x << endl;

}

void h(float x ){

cout << "derived::h(float)" << x <<endl;

}

};

int main()

{

Derived derived;

Base *pb = &derived;

//动态绑定,多态,是覆盖

pb->f(10.0f);

derived.f(10);

cout << endl;

//隐藏,但是不是重载,这里 是静态绑定,根据的是指针的类型,

pb->g(3.14f); // base::g(float) 3.14

derived.g(3.14f);// derived::g(int) 3 将参数强制转换成int 3

// 隐藏,名称相同,参数相同,这里也是根据指着类型进行的静态绑定

pb->h(3.14f);

derived.h(3.14f);

return 0;

}

3.参数的默认值

参数的默认值有编译器在编译的时候自动插入。编写代码的时候将默认的参数值放在函数的声明中,而不要放在函数定义体中。

void Foo(int x = 0, int y = 0);

实现函数的时候就没有必要将默认的参数中写在里面了。

同时如果函数有多个参数那么参数之能够从后面想前面一次默认,不能中间使用没有默认的参数,前面又有默认的参数值。

void Foo(int x = 0, int  y, int z = 0); error

void Foo(int x , int y = 0, int z = 0); right

注意不要出现而二义性的函数,使用默认参数容易出现这种情况。

4.运算符的重载

C++中使用关键字operator加上运算符来表示函数,叫做运算符的重载

Complex Add(const Complex& a, const Complex & b);

Complex operator+(const Complex &a, const Complex &b);

重载++,两种方式

Integer& operator++(){} 前置

Integer& operator++(int){}后置

++ 尽量使用前置版本,效率比较高,因为后置操作,对于大对象的时候,会创建一个临时变量,这样会产生额外的开销。

5.内联函数

C++支持的函数内联机制,提高代码的执行效率。C中使用的宏提高执行的效率,但是宏本省不是代码,只是字符串的替换。这样编译器省却了参数压栈的操作、生成汇编代码的call调用、返回函数,执行return等等,提高了执行速度。最大的确定便是容易出现代码错误。

字符穿替换的时候出现问题

#define MAX(a,b) a>b?a:b

result = MAX(i,j)+2;

改变优先级使用(), #define MAX(a,b) (a)> (b) ?(a):(b)

result = MAX(i++,j);  result = (i++)>(j)?(i++):(j);

内联函数解决了这个问题,同时函数被内联之后,编译器通过上下文进行代码的进一步优化。

6.类型转换

static_cast<dest_type>(source_obj);

dynamic_cast<dest_type>(source_obj);

const_cast<dest_type>(source_obj);

7.const成员函数,就是在函数中不会修改数据成员的代码,如果在程序中调用了其他非const成员函数或者修改数据成员的时候,编译不通过。

使用const修饰函数放在函数的最后面修饰。

Static成员函数不可以是const修饰的,因为static成员函数只是全局函数的一个形式上的封装,而全局函数不存在const之说,何况static成员函数不能够访问类的非静态成员,也就无法修改非静态的成员变量。

追梦的飞飞

于广州中山大学20131002

C++复习11.函数的高级特性的更多相关文章

  1. 002-python函数、高级特性

    1.函数 1.1 定义函数 在Python中,定义一个函数要使用def语句,依次写出函数名.括号.括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回 自定义一个求绝对 ...

  2. Python序列函数、高级特性及高阶函数

    序列函数: enumerate: for循环时记录索引,逐个返回元组(i, item) sorted:返回新的有序列表 zip:压缩将多个序列的对应位置的元素组成元组 zip(*元组列表): 解压缩 ...

  3. python:函数的高级特性

    很多语言中,都允许把函数本身做为参数,传递给其它参数:即所谓的高阶函数.python中也有类似特性: 一.map/reduce.filter.sorted hadoop里的map-reduce思想在p ...

  4. C++函数的高级特性

    对比于 C 语言的函数,C++增加了重载(overloaded).内联(inline).const 和 virtual 四种新机制.其中重载和内联机制既可用于全局函数也可用于类的成员函数,const ...

  5. C++函数的高级特性——小结

    相对于C语言,C++增加了重载(overload).内联(inline).const和virtual四种新机制. 1 重载 只能靠参数列表而不能紧靠返回值类型的不同来区分重载函数.编译器根据参数列表为 ...

  6. python函数高级特性

    掌握了Python的数据类型.语句.函数,基本可以编写出很多有用的程序了.但是Python中,代码不是越多越好,而是越少越好.代码不是越复杂越好,而是越简单越好.基于这一思想,我们来介绍python中 ...

  7. python高级特性和高阶函数

    python高级特性 1.集合的推导式 列表推导式,使用一句表达式构造一个新列表,可包含过滤.转换等操作. 语法:[exp for item in collection if codition] if ...

  8. 02.Scala高级特性:第6节 高阶函数;第7节 隐式转换和隐式参数

    Scala高级特性 1.    课程目标 1.1.   目标一:深入理解高阶函数 1.2.   目标二:深入理解隐式转换 2.    高阶函数 2.1.   概念 Scala混合了面向对象和函数式的特 ...

  9. Python高级特性(3): Classes和Metaclasses(转)

    原文:Python高级特性(3): Classes和Metaclasses 类和对象 类和函数一样都是Python中的对象.当一个类定义完成之后,Python将创建一个“类对象”并将其赋值给一个同名变 ...

随机推荐

  1. ABP官方文档翻译 2.4 日志

    日志 服务端 获取记录器 基类日志记录器 配置 Abp.Castle.Log4Net包 客户端 服务端 ABP使用Castle Windsor`s 日志设备.它可以使用不同的日志类库:Log4Net, ...

  2. 使用svn的过程中check out的文件路径中的文件图标全都加上了“蓝色问号”的解决方案

    (1)你在对同一层目录下创建一个记事本文件,然后把下面这句话复制进去 for /r . %%a in (.) do @if exist "%%a\.svn" rd /s /q &q ...

  3. 照着官网来安装openstack pike之nova安装

    nova组件安装分为控制节点和计算节点,还是先从控制节点安装 1.前提条件,数据库为nova创建库和账户密码来连接数据库 # mysql -u root -p MariaDB [(none)]> ...

  4. 索引原理-btree索引与hash索引的区别

    btree索引与hash索引的区别,之前不清楚,mark一下. Hash索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree索引需要从根节点到枝节点,最后才能访问到页节点这样多 ...

  5. MYSQL数据库里面的所有密码批量MD5加密

    如果你的字段够长度的话:UPDATE users SET password = MD5(password);如果长度不够,可以先增加长度后再做,或者多建一列,完成后删除原来的列!(如passwd)UP ...

  6. 大端和小端(big endian little endian)

    一.大端和小端的问题 对于整型.长整型等数据类型,Big endian 认为第一个字节是最高位字节(按照从低地址到高地址的顺序存放数据的高位字节到低位字节):而 Little endian 则相反,它 ...

  7. visual studio中添加existing web site, website名字附带数字

    用visual studio直接运行website项目 发现有一个conifg文件的配置,路径是solution同级目录下的.vs/config文件夹下有一个applicationhost.confi ...

  8. MySQL 常用运算符

    1.算数运算符 加 mysql> select 1+2; 减 mysql> select 2-1; 乘 mysql> select 2*3; 除 mysql> select 5 ...

  9. 爬虫框架Scrapy之案例一

    阳光热线问政平台 http://wz.sun0769.com/index.php/question/questionType?type=4 爬取投诉帖子的编号.帖子的url.帖子的标题,和帖子里的内容 ...

  10. [Network Architecture]Mask R-CNN论文解析(转)

    前言 最近有一个idea需要去验证,比较忙,看完Mask R-CNN论文了,最近会去研究Mask R-CNN的代码,论文解析转载网上的两篇博客 技术挖掘者 remanented 文章1 论文题目:Ma ...