C++的8个基础语法(中)

简介: C++的8个基础语法

函数重载

顾名思义,可以命名相同的函数,当然,不是在不同的命名空间里。

定义

函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这

些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型不同的问题。

参数类型不同

#include <iostream>
using namespace std;
int add(int x, int y)
{
  return x + y;
}
double add(double x, double y)
{
  return x + y;
}
int main()
{
  int a;
  int b;
  double c;
  double d;
  cin >> a >> b;
  cin >> c >> d;
  int sum;
  sum = add(a, b);//传的两个值都是整形
  cout << sum << endl;
  sum = add(c, d);//传的两个值都是双精度浮点型
  cout << sum << endl;
  return 0;
}

这里就自动识别参数中不同数据类型的传值应该去哪个函数。

参数的个数不同

#include <iostream>
using namespace std;
int add(int x)
{
  return x;
}
int add(int x, int y)
{
  return x + y;
}
int main()
{
  int a;
  int c;
  int d;
  cin >> a;
  cin >> c >> d;
  int sum;
  sum = add(a);
  cout << sum << endl;
  sum = add(c, d);
  cout << sum << endl;
  return 0;
}

这里是自动识别参数的个数。

不同数据类型的参数顺序不同

#include <iostream>
using namespace std;
int add(int x , char y)
{
  return x + y;
}
int add(char x, int y)
{
  return x + y;
}
int main()
{
  int a;
  char b;
  char c;
  int d;
  cin >> a >> b;
  cin >> c >> d;
  int sum;
  sum = add(a, b);
  cout << sum << endl;
  sum = add(c, d);
  cout << sum << endl;
  return 0;
}

这里必须是参数不同的数据类型,不然编译器无法判断传入哪个函数

例:

这里就产生了歧义,也叫做二义性。

C++支持函数重载的原理–名字修饰

在C/C++中,一个程序要运行起来,需要经历以下几个阶段:预处理、编译、汇编、链接。

因为一个项目中,有很多个头文件和源文件组成,函数是很重要的部分,两个不同文件中,一个调用函数一个是函数的定义,这个时候就要找函数的地址把他们链接起来,那么找地址的部分在函数重载是怎么实现的?

我们知道,函数名就是函数地址,那么编译器就会用修饰规则去根据函数重载的函数名和参数进行修饰,变成两个相对接近的名字。

C和C++的符号表区别是这样的:

地址和函数名是编的,但是原理是这样的,C语言中在链接的过程中只有函数名被修饰,C++中函数名和参数一起被修饰。

让我们看一下Linux环境下的g++中C和C++链接时候的情况:

采用C语言编译器编译后结果:

结论:在linux下,采用gcc编译完成后,函数名字的修饰没有发生改变。

采用C++编译器编译后结果:

结论:在linux下,采用g++编译完成后,函数名字的修饰发生改变,编译器将函数参

数类型信息添加到修改后的名字中。

我们可以看出gcc的函数修饰后名字不变。而g++的函数修饰后变成【_Z+函数长度

+函数名+类型首字母】。

再来看看Windows下名字修饰规则

对比Linux会发现,windows下vs编译器对函数名字修饰规则相对复杂难懂,但道理都

是类似的,我们就不做细致的研究了。

通过这里就理解了C语言没办法支持重载,因为同名函数没办法区分。而C++是通过函数修饰规则来区分,只要参数不同,修饰出来的名字就不一样,就支持了重载。

如果两个函数函数名和参数是一样的,返回值不同是不构成重载的,因为调用时编译器没办法区分,调用主要是看参数,和返回值无关。

相关文章
|
2月前
|
Java C# C++
C++ 11新特性之语法甜点1
C++ 11新特性之语法甜点1
31 4
|
2月前
|
编译器 C++ 容器
C++ 11新特性之语法甜点2
C++ 11新特性之语法甜点2
30 1
|
2月前
|
存储 算法 编译器
C++ 11新特性之语法甜点4
C++ 11新特性之语法甜点4
28 0
|
2月前
|
安全 C++ 容器
C++ 11新特性之语法甜点3
C++ 11新特性之语法甜点3
35 0
|
3月前
|
编译器 C++ 容器
C++语言的基本语法
想掌握一门编程语言,第一步就是需要熟悉基本的环境,然后就是最重要的语法知识。 C++ 程序可以定义为对象的集合,这些对象通过调用彼此的方法进行交互。现在让我们简要地看一下什么是类、对象,方法、即时变量。 对象 - 对象具有状态和行为。例如:一只狗的状态 - 颜色、名称、品种,行为 - 摇动、叫唤、吃。对象是类的实例。 类 - 类可以定义为描述对象行为/状态的模板/蓝图。 方法 - 从基本上说,一个方法表示一种行为。一个类可以包含多个方法。可以在方法中写入逻辑、操作数据以及执行所有的动作。 即时变量 - 每个对象都有其独特的即时变量。对象的状态是由这些即时变量的值创建的。 完整关键字
|
4月前
|
Java 编译器 程序员
C++中的语法知识虚继承和虚基类
**C++中的多继承可能导致命名冲突和数据冗余,尤其在菱形继承中。为解决这一问题,C++引入了虚继承(virtual inheritance),确保派生类只保留虚基类的一份实例,消除二义性。虚继承通过`virtual`关键字指定,允许明确访问特定路径上的成员,如`B::m_a`或`C::m_a`。这样,即使基类在继承链中多次出现,也只有一份成员副本,简化了内存布局并避免冲突。虚继承应在需要时提前在继承声明中指定,影响到从虚基类派生的所有后代类。**
|
4月前
|
编译器 C++ 开发者
C++一分钟之-属性(attributes)与属性语法
【7月更文挑战第3天】C++的属性(attributes)自C++11起允许附加编译器指令,如`[[nodiscard]]`和`[[maybe_unused]]`,影响优化和警告。注意属性放置、兼容性和适度使用,以确保代码清晰和可移植。示例展示了如何使用属性来提示编译器处理返回值和未使用变量,以及利用编译器扩展进行自动清理。属性是提升代码质量的工具,但应谨慎使用。
139 13
|
5月前
|
编译器 程序员 C++
C++一分钟之-属性(attributed)与属性语法
【6月更文挑战第28天】C++的属性为代码添加元数据,帮助编译器理解意图。C++11引入属性语法`[[attribute]]`,但支持取决于编译器。常见属性如`nodiscard`提示检查返回值,`maybe_unused`防止未使用警告。问题包括兼容性、过度依赖和误用。使用属性时需谨慎,确保团队共识,适时更新以适应C++新特性。通过示例展示了`nodiscard`和`likely/unlikely`的用法,强调正确使用属性能提升代码质量和性能。
84 13
|
5月前
|
编译器 C语言 C++