C++基础学习笔记----第四课(函数的重载、C和C++的相互调用)

原创 2013年12月02日 21:47:38

本节主要讲了函数重载的主要概念以及使用方法,还有C和C++的相互调用的准则和具体的工程中的使用技巧。

函数重载

1.基本概念

函数重载就是用同一个函数名来定义不同的函数。使用不同的函数参数来搭配同一个函数名。基本例程如下:

#include <stdio.h>
#include <string.h>

int func(int a)
{
	return a;
}

int func(int x, int y)
{
	return x*y;
}

int func(int a, int b, int c)
{
	return a + b + c; 
}

int func(char *p)
{
	return strlen(p);
}

int main()
{
	printf ("func(1) = %d\n", func(1));
	printf ("func(1,2) = %d\n", func(1,2));
	printf ("func(1,2,3) = %d\n", func(1,2,3));
	printf ("func(abcdef) = %d\n", func("abcdef"));
}

2.重载条件

①参数个数不同。

②参数类型不同。

③参数顺序不同。
课程里的老师说这三个条件是不按住顺序的,也就是只要有一个条件满足就可以判断对哪个函数进行重载,但是我觉得有问题存在。

例程:

#include <stdio.h>
#include <string.h>

int func(const char *p, int b)
{
	return strlen(p); 
}

int func(int b, const char *p)
{
	return b ;
}

int main()
{
	printf ("func(1,ac) = %d\n", func(1,"ac"));
	printf ("func(ac, 1) = %d\n", func("ac", 1));
}
从上面的程序证明了条件③,函数的参数顺序不同函数可以进行重载。在C++中可以将功能类似的函数都重载起来,仅仅让编译根据参数的不同来实现不同的编译,从而实现重载函数的识别和调用。

3.函数的重载与函数默认参数的冲突

例程:

#include <stdio.h>
#include <string.h>

int func(int a, int b, int c = 0)
{
	return a * b * c; 
}

int func(int a, int b)
{
	return a + b;
}

int main()
{
	printf ("func(1,2) = %d\n", func(1,2));
}
这个时候编译器会承认两个函数func是重载函数,但是编译器会报错,错误报告是:对重载函数的调用不明确。这个叫做程序的二义性。当我们使用函数重载的时候就不要使用函数的默认参数,当我们使用函数的默认参数的时候就不要进行函数的重载。

4.C++编译器调用重载函数的准则

我们在进行函数重载的时候会有很多个同名的函数,这些同名函数最后是怎么被编译成为可执行程序的,这些事依赖于C++编译器的编译准则的。

在匹配成功的前两准则中前面的小例子都可以体现出来,下面的历程是针对通过默认类型转换匹配实参的准则。历程如下:

#include <stdio.h>
#include <string.h>

int func(int a, int b)
{
	return a + b;
}

int func(int b)
{
	return 1;
}

int main()
{
	printf ("func(1,2) = %d\n", func('a',2));
}
这里将‘a’转化为ASII码来与函数的参数进行匹配。

问题:老师说函数的重载三个准则是没有顺序的,但是当出现第二条和第三条冲突的时候在VS2008的C++编译环境下还是有顺序的,函数还是会先对完全匹配的进行重载。例程如下:

#include <stdio.h>
#include <string.h>

int func(int a, int b)
{
	return a + b;
}

int func(char a, int b)
{
	return 1;
}

int main()
{
	printf ("func(1,2) = %d\n", func('a',2));
}
上述程序的打印结果是1

5.重载函数的注意事项

①重载函数在本质上是相互独立的不同函数。

②重载函数的类型是不同的。

③函数的返回值不能作为重载函数的依据。

④重载函数是由函数名和参数列表决定的。

6.函数重载与函数指针

当使用重载函数名对函数指针进行赋值时,根据重载规则与函数指针参数列表一样的函数定为重载函数,同时函数类型和函数指针的类型要求十分严格。
例程:
#include <stdio.h>
#include <string.h>

int func(int x) // int(int a)
{
    return x;
}

int func(int a, int b)
{
    return a + b;
}

int func(const char* s)
{
    return strlen(s);
}

typedef int(*PFUNC)(int a); // int(int a)

int main(int argc, char *argv[])
{
    int c = 0;
    PFUNC p = func;
    
    c = p(1);
    
    printf("c = %d\n", c);
    
    printf("Press enter to continue ...");
    getchar();	
    return 0;
}

C和C++的相互调用

1.在实际的项目中融合C和C++代码是不可避免的(想起了学习嵌入式的岁月,尽管是菜鸟)。虽然C++编译器能够兼容C语言的编译方式,但C++编译器会优先使用C++的方式进行编译利用extern关键字强制让C++编译器对代码进行C方式编译。C++和C的编译方式是不同的,因为语言是不同的,这些方式主要包括一些规则和一些约束等。

2.C++(main.cpp)调用C语言(add.c)编写的函数

代码如下:

main.cpp

#include <stdio.h>

extern "C"
{
#include "add.h"
}


int main()
{
    printf("1 + 2 = %d\n", add(1, 2));
    
    return 0;
}
add.c

#include "add.h"

int add(int a, int b)
{
    return a + b;
}
编译流程:①gcc add.c -o add.o 或 gcc -c add.c ②g++ main.cpp add.o就可以了 

3.C语言(main.c)调用C++(add.cpp)编写的函数
代码如下:

main.c

#include <stdio.h>
#include "add.h"

int main()
{
    printf("1 + 2 = %d\n", add(1, 2));
    
    return 0;
}
add.cpp

extern "C"
{

#include "add.h"

int add(int a, int b)
{
    return a + b;
}

}
编译流程:①g++ -c add.cpp②gcc main.c -lstdc++ add.o 
问题:这里相互编译的过程是调用了两个不同的编译器gcc和g++,但是里面的标准以及函数链接库肯定会存在差异,也就是说虽然C++是C的发展,但是仍然会产生问题,不过这个问题是由编译器来掩盖的?还是这就是C++的先进所在?两个编译器的差别以及这两种标准的融合?

4.C++和C相互调用的同意解决方案 

 _cplusplus是c++编译器内置的标准宏定义,让c代码既可以通过c编译器的编译,又可以在c++编译器中以c的方式进行编译(使用条件编译),代码如下:

#include <stdio.h>
#include <string.h>


#ifdef __cplusplus
extern "C" {
#endif

int func(int a, int b)
{
    return a + b;
}

int func(const char* s)
{
    return strlen(s);
}

#ifdef __cplusplus
}
#endif

int main(int argc, char *argv[])
{
    printf("Press enter to continue ...");
    getchar();	
    return 0;
}
注意:在extern “C”的两个大括号之间可以放函数的定义或者函数的声明,不单单是函数的定义。
5.C++编译器不能以C语言的方式编译多个重载函数

错误代码示例:

#ifdef __cplusplus
extern "C"{
#endif

void f()
{
	
}

void f(int i)
{

}
#ifdef __cplusplus
}
#endif

int main()
{
	return 0;
}

相关文章推荐

2011年冬斯坦福大学公开课 iOS应用开发教程学习笔记(第四课) Views 视图

第四课名称: Views 视图 课程开始老师怀念了一会老乔。接着介绍这次的课程分为两部分,一部分是Calculator的Demo,一部分是Views. 课程开始到第四课,其实斯...

斯坦福大学公开课 iOS应用开发教程学习笔记(第四课) Views 视图

第四课名称: Views 视图 课程开始老师怀念了一会老乔。接着介绍这次的课程分为两部分,一部分是Calculator的Demo,一部分是Views. 课程开始到第四课,其实斯坦福的课程里是...
  • Dev_Ho
  • Dev_Ho
  • 2014年11月04日 13:27
  • 3248

【C++】【学习笔记】【006】函数的重载

重载的概念: 1、C++里的函数重载(overloading)机制比我们此前见到的东西都高深,这种语言的灵活性和强大功能在它身上体现得淋漓尽致。 2、所谓函数重载的实质就是用同样的名字再定义一个有...
  • jay_yin
  • jay_yin
  • 2014年11月09日 16:17
  • 498

【C++】学习笔记四十二——函数重载

函数重载函数多态(函数重载)使我们能够使用多个同名的函数。“多态”是指有多种形式。函数多态允许函数有多种形式,函数重载是指可以有多个同名的函数,对名称进行了重载。这两个术语指的是同一件事。 可以通过...
  • budf01
  • budf01
  • 2017年06月05日 18:25
  • 765

C++ Primer学习笔记——$14 操作符重载、函数对象及类类型转换

题记:本系列学习笔记(C++ Primer学习笔记)主要目的是讨论一些容易被大家忽略或者容易形成错误认识的内容。只适合于有了一定的C++基础的读者(至少学完一本C++教程)。  作者: tyc611,...
  • whycold
  • whycold
  • 2011年01月19日 15:09
  • 730

C++primer学习笔记-----6.4函数重载

【如果同一作用域内的几个函数名字相同但形参列表不同,我们称之为重载函数。 函数重载通常用于逻辑功能相同,但处理对象类型不同的函数,以此减轻程序员记名字的压力。】 【重载和const 形参:...

C++函数的重载的学习笔记

Java中有方法的重载和重写,在Java中方法重载的定义是:在同一个类中具有2个或2个以上的方法他们的方法名称完全相同,只是方法的参数的个数不同或者方法参数的类型不同的这种方法就叫方法重载,在C++中...
  • qhs1573
  • qhs1573
  • 2013年10月04日 16:03
  • 648

黑马程序员_java的语言基础组成最终篇(对第四课函数和数组的总结)

android培训、java培训、期待与您交流! 通过今天对java语言基础组成中的函数和数组的学习,我来给自己的学习内容做下简单直白的总结: 首先,让我来先说说函数,它是定义在类中,...

【C++第四课】---类的封装

一、类的组成 一个类通常分为以下两部分 1、类的实现细节(只有在创建类得时候才关心) 2、类得使用方式(只有在使用类得时候才关心) 二、C++中类的封装 1、成员变量(C++中表示类属性的变量) ...

【C++探索之旅】第一部分第四课:内存,变量和引用

变量,是基础; 引用,是C++的重要内容
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++基础学习笔记----第四课(函数的重载、C和C++的相互调用)
举报原因:
原因补充:

(最多只允许输入30个字)