C++鸟瞰(个人心得)

头文件

C++和C一样,在源文件的头部需要加入头文件,来告诉预处理器你需要用到什么库。编写方式也和C语言一样,不过基础头文件不是stdlib.h而是iostream,名字划分为io和stream。

stream翻译过来就是“流”的概念,流的概念不是C++特有的,而是Linux下的一个概念,在Linux下一切皆文件,输入输出也是文件,称为输入流输出流,编程语言输入输出的背后就是用标准输入标准输出来实现的,标准输入流默认绑定在键盘输入,标准输出默认绑定在终端窗口,标准输入输出可以通过重定向绑定到文件或者其他上。

#include<iostream>  //通用的header file使用扩折号
#include"my_self_header_file.h" //自己编写的header文件使用英语双引号

C++在Linux下的默认include查找路径是/usr/local/include和/usr/local/include,当安装了新的库时,要么将该库的include路径加到C_INCLUDE_PATH,要么在默认路径中加一个软链接指向库的include文件夹。我更推荐第二种,便于管理。

命名空间

C++有非常多的开发库,这些库中有很多算法函数名称是一样的,当同时用到两个不同的功能库中一样名称的函数时应该如何区分是来自哪个空间的呢?为了解决这个问题,C++中定义了命名空间这个概念,当出现上面的问题时,可以在函数的前面加上命名空间的名字,就可以区分了。

#include<iosteam>
using namespace std; 
// std 就是基础标准库的命名空间
// using namespace std的意思就是声明我要用到这个命名空间,这样就不需要在变量前加std了
//大型项目最好不要这样直接声明使用整个命名空间,会导致命名空间污染,使用在函数前面加命名空间名称的方式较好。
int main(){cout<<"hello"<<endl;// 如果前面没有声明命名空间,那么就要使用下面这行代码来代替// std::cout<<"hello"<<std::endl;return 0;
}

当我们在参与一个大型项目的时候,我们经常在不同的模块中可能会实现两个名称相同的函数,为了解决这个问题,我们可以进行自定义命名空间,下面代码为如何自定义一个命名空间

#include<iostream>namespace mynamespace{void func(){};
}int main(){mynamespace::func();return 0;
}

命名空间不仅仅对函数有用,也对变量有用。但是有一些常见变量我们可能在一个程序中就会用到很多个同名的,比如temp这个名字,使用频率非常高,难道要都给他们定义一个命名空间吗?C++中的变量声明和函数声明都是有自己的使用空间限制的,出了这个空间声明就无效了,一般都是以{}为一个空间,英文叫一个scope,可以根据大小分为global scope和local scope

其实namespace也是一个scope

#include<iostream>
int globalnum; //这是一个全局变量,就是说在全局通用int main{std::cout<<globalnum<<std::endl;for(int i=0;i<10;i++){std::cout<<globalnum<<std::endl; //可以}std::cout<<i<<std::endl; //会报错,因为已经出了scopereturn 0;
}

面向对象编程

C++是一个较为多元的编程语言,可以满足多种编程范式,C++可以进行面向对象编程。

  • 类class,是抽象的,是一种用户自定义的数据类型,它是一种封装了数据和函数的组合。类中的数据称为成员变量,函数称为成员函数。类可以被看作是一种模板,可以用来创建具有相同属性和行为的多个对象。
  • 对象/实例,是实实在在的,是类的实体化。

面向对象编程比较符合人的直觉,但是想要写出好的面向对象代码不能只靠直觉,面向对象有23种常见的设计模式,是进行面向对象编程所必学的。

#include<iostream>
#include<string>
class Person{
public:Person(const string namestr=0); //构造函数Person(const Person& originalperson);//拷贝函数 构造函数,拷贝函数,析构函数,默认不用写函数返回类型Person& operator= (const Person& originalperson); //拷贝赋值函数inline std::string getName(){return name;}~Person(){};  //析构函数
private:std::string name;int height;int age;
};
inline Person::Person(const std::string namestr)
{if(namestr.size()){name = std::string(namestr);}else{name = std::string();}
}
int main()
{Person bighammer("王大锤");std::cout<<bighammer.getName()<<std::endl;return 0;
}

上面实现了一个最简单的类。麻雀虽小,五脏俱全。一个类最少应该包括以下几部分:

  • 普通构造函数
  • 析构函数
  • 拷贝构造
  • 赋值运算重载

C++中初始化对象可以使用malloc和free,也可以使用new和delete,new和delete会调用类的构造函数和析构函数,可以避免空指针的存在。【二者初始化的对象所在位置也不同,new时在自由存储区为对象动态分配内存,malloc是在堆栈上分配空间】
必须实现拷贝构造的原因是如果不实现拷贝构造,C++会自动为你实现一个完全复制的拷贝构造,如果你的类里面有指针,指针也会被复制过去,这样就可能导致两个对象指向同一个数据,引发bug。

C++标准库 & 模板编程

C++标准库是对C标准库的扩充,对C的库稍作修改,并增加了面向对象以及模板编程的内容。
C++另一种常用编程范式就是模板编程或者说泛型编程,泛型编程的思想是逻辑代码独立于任何特定类型,能够有效实现代码复用。
模板可以分为函数模板和类模板,模板参数又可以分为类型模板参数和非类型模板参数,两两结合,一共四种可能:

template<typename T>  // 类型函数模板
T funcadd(T a, T b)
{T addhe = a + b;return addhe;
}
template<int a, int b>  // 非类型函数模板,浮点数不能作为非类型模板参数
int funcaddv2()
{int addhe = a + b;return addhe;
}
template<typename T> //类型类模板
class MyClass
{
private:T* temp;void func();
}
template<typename T>
void MyClass<T>::func(){}template<int id> // 非类型类模板
class MyClass2
{
private:int number=id;
}
//不过非类型一般都是更类型一块儿用,例如array类
template<typename T,int size>
class Array
{
private:T arr[size];void func2();
}
template<typename T,int size>
void func2(){}

不管是函数模板还是类模板,都是在用到时才能生成一个实例,如果多文件编程,为了防止产生多个实例,可以在类模板的文件中显式实例化:

template MyClass<float> //进行显式实例化
extern template MyClass<float> //其他文件中就只能进行外部实例化声明

这里的实例化是指将模板实例化,生成对应类型的代码,而不是面向对象编程中的将一个类实例化成一个对象。

现代C++中还支持模板特化和偏特化,如果一个模板对于某些特定的类型需要进行单独编写代码,就叫特化,如果所有类型都要进行特殊编写代码,就叫全特化,如果局部类型进行特化,称为偏特化:

template<>
struct TC<int, int>
{TC(){cout << "TC<int,int>特化版本的构造函数" << endl;}// 这里可以对特化的版本做单独的处理
}struct TC<int, double>
{TC(){cout << "TC<int,double>特化版本的构造函数" << endl;}// 这里可以对特化的版本做单独的处理
}template <typename U> // 偏特化,3个参数绑定2个。
struct TCP<int, U, double>
{TCP(){cout << "TCP偏特化版本的构造函数" << endl;}void functest(){cout << "TCP偏特化版本"<< endl;}
}

除此之外,还有模板参数范围特化,可变参数模板,模板模板参数等等,自行了解。

STL标准模板类就是一个模板编程的集大成者,标准模板库STL主要由以下几部分组成:

  • 容器类:数据类型,其中又分为序列容器和非序列容器
  • 算法类:适用于容器类的常见算法的实现,如sort,search
  • 迭代器:适用于容器类的迭代器
  • 适配器:可变容器,迭代器或者函数对象接口的一种组件
  • 函数对象:用类型包装函数
  • 分配器:进行内存分配

现代C++

随着C++的发展,引入了不少新的特性以及编程范式,目前大多将C++11以后的版本,称为现代C++。C++11更新的特性非常多,网上都说C++11是C++跨时代的发展,可以参考:《深入理解C++11:C++11新特性解析与应用》这本书,讲的很好,对于了解C++11很有帮助。

函数式编程

函数编程的思想是:程序是函数定义的表达式树,这些函数将一个值映射到另一个值,而不是传统的状态机模型意义下的命令式语句。
C++11中引入了lambda匿名函数,使得C++进行函数式编程更为容易,函数式编程现在很火,这两年发展迅猛的Rust也是函数式编程的忠实拥护,基本上目前大部分编程语言都支持函数式编程,匿名函数,闭包,是函数式编程中的重要概念。

C++工具 & 功能库

C++因为其标准委员会只负责制定标准,不负责实现,以及C++实现的不统一,导致其工具也非常多。MSVC和GCC和Clang各自都有很多配套的工具,所以学习C++不光要会语法以及特性,还要学习配套的工具和相应领域的工具库,

工具:

Cmake:用于自动化配置编译,生成makefile
ninja:构建系统,也是用于构建cpp项目的
gdb:调试工具
gprof:性能测试工具,来自GNU Binutils,其他的可以不会,这个一定要会用。
valgrind:内存泄漏检测工具

功能库

计算机视觉:OpenCV
矩阵计算:Eigen
客户端开发:Qt
深度学习推理引擎:Onnxruntime

后续想到什么再慢慢缝缝补补吧,C++太大了,太繁杂了,令人眼花缭乱

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WebSocket:实现客户端与服务器实时通信的技术

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

3、Design Script之对象类型

布尔值 布尔值Boolean——true/false是Design Script的常量对象&#xff0c;用于表示真/假值 boolTrue true; boolFalse false&#xff1b; 在数字环境中&#xff0c;布尔值的行为类似于整数0和1 布尔值也可以作为Yes和No来引用 数字 int(integer)——整数 Double&#…

JS的对象

目录 对象&#xff1a;object 对象的创建&#xff1a; 利用对象字面量创建对象&#xff1a; 使用new来进行创建对象&#xff1a; 利用构造函数来创建对象&#xff1a; new的执行&#xff1a; 对象属性的遍历&#xff1a;for in ------ 相当于JAVA的工具类&#xff0c;直…

docker学习入门篇

1、docker简介 docker官网&#xff1a; www.docker.com dockerhub官网&#xff1a; hub.docker.com docker文档官网&#xff1a;docs.docker.com Docker是基于Go语言实现的云开源项目。 Docker的主要目标是&#xff1a;Build, Ship and Run Any App, Anywhere(构建&…

每日一题——LeetCode2129.将标题首字母大写

方法一 个人方法 将字符串转为数组&#xff0c;遍历数组&#xff0c;对数组的每一个元素&#xff0c;先全部转为小写&#xff0c;如果当前元素长度大于2&#xff0c;将第一个字符转为大写形式 var capitalizeTitle function(title) {titletitle.split( )for(let i0;i<tit…

概要了解postman、jmeter 、loadRunner

postman还蛮好理解的&#xff0c;后续复习的话着重学习关联接口测试即可&#xff0c;感觉只要用几次就会记住&#xff1a; 1 从接口的响应结果当中提取需要的数据 2 设置成环境变量/全局变量&#xff08;json value check 、set environment para 3写入到下一个接口的请求数据中…

工具-百度云盘服务-身份认证

目标 通过百度网盘API的方式去获取网盘中的文件&#xff0c;要实现这的第一步就是需要获取网盘的权限。资料(参考) 如果期望应用访问用户的网盘文件&#xff0c;则需要经过用户同意&#xff0c;这个流程被称为“授权”。百度网盘开放平台基于 OAuth2.0 接入授权。OAuth2.0 是…

1688 API商品详情接口与ERP系统的集成

API接口与ERP系统集成的应用主要包括数据同步、业务流程自动化和信息共享三个方面。 数据同步&#xff1a;通过API接口&#xff0c;ERP系统可以与其他系统之间进行数据的交换和同步。比如&#xff0c;将销售订单从电商平台自动导入到ERP系统中&#xff0c;然后将发货信息同步回…

Kettle安装使用手册

Kettle安装使用手册 目录 1 KETTLE 介绍 5 1.1. 核心组件 5 1.2. 组成部分 5 1.3. 概念模型 6 1.3.1. Transformation(转换) 6 1.3.2. Steps(步骤) 7 1.3.3. Hops(节点连接) 7 1.3.4. Jobs(工作) 7 1.3.5. Variable(变量) 8 1.4. 查看版本 9 1.5. 选项设置 10 2 安装…

OEKO-TEX®2024新规定于4月1日正式生效

OEKO-TEX协会参照最新的科学发现和法律法规&#xff0c;就测试标准、限量值和指南发布了年度更新。新规定将在常规过渡期结束后&#xff0c;于2024年4月1日正式生效&#xff08;PFAS限量值例外&#xff09;。新的总氟(TF)限量值取代了之前的可萃取有机氟(EOF)&#xff0c;该更新…

关于分布式分片,你该知道的事儿

关于分布式分片&#xff0c;你该知道的事儿 前言一、关于分片方式的那些事儿1.1 按照Hash划分1.2 按照区间范围划分1.3 按照数据量划分1.4 来些例子1.4.1 Redis的分片划分1.4.2 Mongo的分片划分 二、关于分区再平衡的那些事儿2.1 基于固定分片数量2.2 基于动态分片数量2.3 基于…

DevOps实战:Docker、Kubernetes与Jenkins的完美融合

DevOps与容器化技术&#xff1a;Docker、Kubernetes和Jenkins 引言 在软件开发领域&#xff0c;DevOps文化和容器化技术已经成为当今最热门的话题之一。DevOps的目标是缩短开发和运维之间的距离&#xff0c;提高软件交付的速度和质量。而容器化技术&#xff0c;如Docker和Kub…

[Affinity笔记]Affinity Photo自设快捷键笔记(附配置文件)

最近用Affinity Photo设计2D角色&#xff0c;把默认的快捷键改了一下&#xff0c;写篇笔记以作备忘 AffinityPhoto自定义快捷键 CSDN下载 图层命令 命令快捷键说明合并图层Ctrl MMerge合并所有可见图层Ctrl Shift M锁定图层Ctrl LLock解锁图层Shift L解锁全部图层Ctrl S…

计算机毕业设计 | SSM 在线毕业论文管理 线上考试成绩教务管理系统(附源码)

1&#xff0c; 绪论 研究背景 系统管理也都将通过计算机进行整体智能化操作&#xff0c;对于论文管理系统所牵扯的管理及数据保存都是非常多的&#xff0c;例如管理员&#xff1b;首页、系统用户&#xff08;管理员、学生、老师&#xff09;模块管理&#xff08;指导教师、课…

为什么不要使用elasticsearch

互联网上有很多文章&#xff0c;都在讲为什么要使用elasticsearch&#xff0c;却很少有人讲为什么不要使用elasticsearch。作为深入研究elasticsearch四年&#xff0c;负责公司万亿级别检索的操盘手&#xff0c;借着这篇文章&#xff0c;给大家分享一下&#xff0c;为什么不要使…

单元测试框架unittest D15

1、unittest 单元测试框架 TestCase&#xff1a;一个testcase的实例就是一个测试用例 TestSuite&#xff1a;多个测试用例集合在一起。TestLoader&#xff1a;是用来加载TestCase到TestSuite中的 TextTestRunner&#xff1a;用来执行测试用例的 fixture&#xff1a;测试用例…

C++11 std::thread

std::thread std::thread是一个用于创建和管理线程的类。它可以让程序在多个并发执行的线程中执行不同的任务。下面是std::thread的一些常用用法介绍&#xff1a; 创建线程&#xff1a; void myFunction(int arg1, double arg2) {// 线程执行的代码 } std::thread t(myFunct…

Vue3全家桶 - VueRouter - 【2】重定向路由

重定向路由 在路由规则数组中&#xff0c;可采用 redirect 来重定向到另一个地址&#xff1a; 通常是将 / 重定向到 某个页面&#xff1b; 示例展示&#xff1a; router/index.js&#xff1a;import { createRouter, createWebHashHistory, createWebHistory } from vue-route…

混合测试写一写

题目 服务器IP地址规划&#xff1a;client&#xff1a;12.0.0.12/24&#xff0c;网关服务器&#xff1a;ens36:12.0.0.1/24、ens33&#xff1a;192.168.44.1/24&#xff0c;Web1&#xff1a;192.168.44.30/24&#xff0c;Web2&#xff1a;192.168.44.50/24&#xff0c;Nginx&am…

ocr关键信心提取数据集

doc/doc_ch/dataset/kie_datasets.md PaddlePaddle/PaddleOCR - Gitee.com https://huggingface.co/datasets/howard-hou/OCR-VQA OCR-VQA Dataset | Papers With Code