Effective C++ 2e Item50

RK3588 InsightFace人脸识别移植及精度测试全解析 本文详细介绍了如何在RK3588平台上移植InsightFace人脸识别模型并进行精度验证。通过PyTorch转ONNX、ONNX转RKNN量化模型的关键步骤,实现了INT8量化模型的部署。测试数据显示,该模型在LFW数据集上达到99.43%的准确率(接近官方99.52%),推理时间仅14.23ms。ROC曲线和相似度分布图表明模型区分能力优秀,AUC超过0.99,满足实际应用需求。文中还详解了量化原理、环境搭建和测试方法,为边缘设备部署人脸识别提供了完整解决方案。 阅读详情

条款50: 提高对C++的认识

C++中有很多 "东西":C,重载,面向对象,模板,例外,名字空间。这么多东西,有时让人感到不知所措。怎么弄懂所有这些东西呢?

C++之所以发展到现在这个样子,在于它有自己的设计目标。理解了这些设计目标,就不难弄懂所有这些东西了。C++最首要的目标在于:

· 和C的兼容性。很多很多C还存在,很多很多C程序员还存在。C++利用了这一基础,并建立在 ---- 我是指 "平衡在" ---- 这一基础之上。

· 效率。作为C++的设计者和第一个实现者,Bjarne Stroustrup从一开始就清楚地知道,要想把C程序员争取过来,就要避免转换语言会带来性能上的损失,否则他们不会对C++再看第二眼。结果,他确信C++在效率上可以和C匹敌 ---- 二者相差大约在5%之内。

· 和传统开发工具及环境的兼容性。各色不同的开发环境到处都是,编译器、链接器和编辑器则无处不在。从小型到大型的所有开发环境,C++都要轻松应对,所以带的包袱越轻越好。想移植C++?你实际上移植的只是一种语言,并利用了目标平台上现有的工具。(然而,往往也可能带来更好的实现,例如,如果链接器能被修改,使得它可以处理内联和模板在某些方面更高的要求)

· 解决真实问题的可应用性。C++没有被设计为一种完美的,纯粹的语言,不适于用它来教学生如何编程。它是设计为专业程序员的强大工具,用它来解决各种领域中的真实问题。真实世界都有些磕磕碰碰,因此,程序员们所依赖的工具如果偶尔出点问题,也不值得大惊小怪。

以上目标阐明了C++语言中大量的实现细节,如果没有它们作指导,就会有摩擦和困惑。为什么隐式生成的拷贝构造函数和赋值运算符要象现在这样工作呢,尤其是指针(参见条款11和45)?因为这是C对struct进行拷贝和赋值的方式,和C兼容很重要。为什么析构函数不自动被声明为virtual(参见条款14),为什么实现细节必须出现在类的定义中(参见条款34)呢?因为不这样做就会带来性能上的损失,效率很重要。为什么C++不能检测非局部静态对象之间的初始化依赖关系(参见条款47)呢?因为C++支持单独编译(即,分开编译源模块,然后将多个目标文件链接起来,形成可执行程序),依赖现有的链接器,不和程序数据库打交道。所以,C++编译器几乎不可能知道整个程序的一切情况。最后一点,为什么C++不让程序员从一些繁杂事务如内存管理(参见条款5-10)和低级指针操作中解脱出来呢?因为一些程序员需要这些处理能力,一个真正的程序员的需要至关重要。

关于C++身后的设计目标如何影响语言行为的形成,以上介绍远远不够。要想覆盖所有的内容,将需要一整本书;方便的是,Stroustrup写了一本。这本书是 "The Design and Evolution of C++"  (Addison-Wesley, 1994),有时简称为 "D&E"。读了它,你会了解到有哪些特性被增加到C++中,以什么顺序,以及为什么。你还会知道哪些特性被放弃了,以及为什么。你甚至可以了解到一些幕后故事,如dynamic_cast(参见条款39和M2)如何被考虑,被放弃,又被考虑,最后被接受 ---- 以及为什么。如果你理解C++有困难,D&E将为你驱散心头的疑云。

对于C++如何成为现在的样子,"The Design and Evolution of C++" 提供了丰富的资料和见解,但它绝对不是正式的语言规格说明。对此你得求助于C++国际标准,一本令人印象深刻的长达700多页的正式文本。在那儿你可以读到象下面这样刻板的句子:

一个虚函数调用所使用的缺省参数是表示对象的指针或引用的静态类型所决定的虚函数所声明的缺省参数。派生类中的重载函数不获取它重载的函数中的缺省值。

这段话是条款38("决不要重新定义继承而来的缺省参数值")的基础,但我期望我对这个论题的论述比上面的原文多少更让人容易理解一些。

C++标准不是临睡前的休闲读物,而是你最好的依靠 ---- 你的 "标准" 依靠 ---- 如果你和其他人(比如,编译器供货商,或采用其它工具编程的开发人员)对什么东西是或不是C++有分歧的话。标准的全部目的在于,为解决这类争议提供权威信息。

C++标准的官方名称很咬口,但如果你需要知道,就得知道。这就是:International Standard for Information Systems----Programming Language C++。它由International Organization for Standardization (ISO)第21工作组颁布。(如果你爱钻牛角尖,它实际上是由ISO/IEC JTC1/SC22/WG21颁布的----我没有添油加醋)你可以从你的国家标准机构(在美国,是ANSI,即American National Standards Institute)定购正式C++标准的副本,但C++标准的最新草稿副本 ---- 和最终文件十分相近(虽然不完全一样)---- 在互联网上是免费提供的。可以找到它的一个好地方是 "the Cygnus Solutions Draft Standard C++ Page" (http://www.cygnus.com/misc/wp/),互联网上变化速度很快,如果你发现这个网站不能连接也不要奇怪。如果是这样,搜索引擎一定会帮你找到一个正确的URL。

我说过,"The Design and Evolution of C++" 对于了解C++语言的设计思想很有好处,C++标准则明确了语言的具体细节;如果在 "D&E千里之外的视野" 和 "C++标准的微观世界" 之间存在承上启下的桥梁那就太好了。教程应当适合于这个角色,但它们的视角往往偏向于标准,更侧重于说明什么是语言,而没有解释为什么。

进入ARM吧。ARM是另一本书,"The Annotated C++ Reference Manual" (Addison-Wesley, 1990),作者是Margaret Ellis和Bjarne Stroustrup。这本书一出版就成为了C++的权威,国际标准就是基于ARM(和已有的C标准)开始制定的。这几年间,C++标准和ARM中的说明在某些方面有分歧,所以ARM不再象过去那样具有权威性了。但它还是很具参考价值,因为它所说的大多数还是正确的;所以,在C++领域中,有些厂家还是坚持采用ARM规范,这并不少见,毕竟,标准只是最近才定下来。

然而,使得ARM真正有用的不是它的RM部分(the Reference Manual),而是A部分(the annotations):注释。针对C++的很多特性 "为什么" 要象现在这样工作,ARM提供了全面的解释。这些解释D&E中也有一些,但大多数没有,你确实需要了解它们。例如,第一次碰到下面这段代码,大部分人会为它发疯:

class Base {
public:
  virtual void f(int x);
};

class Derived: public Base {
public:
  virtual void f(double *pd);
};

Derived *pd = new Derived;
pd->f(10);                            // 错误!

问题在于Derived::f隐藏了Base::f,即使它们取的是不同的参数类型;所以编译器要求对f的调用取一个double*,而10这个数字当然不行。

这不很合理,但ARM对这种行为提供了解释。假设调用f时,你真的是想调用Derived中的版本,但不小心用错了参数类型。进一步假设Derived是在继承层次结构的下层,你不知道Derived间接继承了某个基类BaseClass,而且BaseClass中声明了一个带int参数的虚函数f。这种情况下,你就会无意中调用了BaseClass::f,一个你甚至不知道它存在的函数!在使用大型类层次结构的情况下,这种错误会时常发生;所以,为了防患于未然,Stroustrup决定让派生类成员按名字隐藏掉基类成员。

顺便指出,如果想让Derived的用户可以访问Base::f,可以很容易地通过一个using声明来完成:

class Derived: public Base {
public:
  using Base::f;                   // 将Base::f引入到
                                   // Derived的空间范围
  virtual void f(double *pd);
};

Derived *pd = new Derived;
pd->f(10);                         // 正确,调用Base::f

对于尚不支持using声明的编译器,另一个选择是采用内联函数:

class Derived: public Base {
public:
  virtual void f(int x) { Base::f(x); }
  virtual void f(double *pd);
};

Derived *pd = new Derived;
pd->f(10);                 // 正确,调用Derived::f(int),
                           // 间接调用了Base::f(int)

借助于D&E和ARM,你会对C++的设计和实现获得透彻理解,从而可能参悟到:有时候,看似巴洛克风格的建筑外观之后,是合理严肃的结构设计。(译注:巴洛克风格的建筑极尽富丽堂皇、粉装玉琢,因而结构复杂,甚至有点怪异)将这些理解和C++标准的具体细节结合起来,你就矗立于软件开发的坚实基础之上,从而走向真正有效的C++程序设计之路。

ThingsBoard入门实战(二):ThingsBoard 设备接入 文章目录ThingsBoard 设备接入一、设备配置/设备类型二、设备三、设备接入HTTPCOAPMQTT四、下一步 ThingsBoard 设备接入 设备接入并不一定需要真正的设备,我们可以通过程序。或者命令来模拟设备,向平台发送信息。 这节我们先为用户分配一个设备,然后通过模拟设备命令更新设备的状态(遥测值)。 一、设备配置/设备类型 添加一个叫"路灯"的设备配置。 设备配置听起来比较抽象,可以认为是设备类型或者是设备类型的配置。实际上,ThingsBoard 中很多时候让选择设备类型,就是选的这个。 阅读详情

相关推荐

GD32官方资料学习体系(主要包括MCU选型、原理图PCB设计、软件开发入门及用户手册等)

大部分还未更新,先占个坑,日后更新…… 目前国外芯片涨价涨的离谱(就是在说ST),国内最好的替代就是兆易创新出的系列芯片了。但是官方资料繁杂,小白上手不易,因此边入门边记录,也给后来者根据官方资料可以有一个较为完整的学习体系。

Eddie的博客 1万+

C++的介绍与认识

学习了C语言的知识,今天小编将进军C++的知识,本篇博客可能略微枯燥,主要是对C++的相关介绍和认识,以及学习路线,下节将正式进入C++的学习。C++起源于C语言,但通过引入面向对象编程(OOP)和泛型编程的特性,使其功能更为丰富和灵活。它被广泛应用于系统/应用程序开发、游戏开发、嵌入式系统等领域,因其性能优越和可扩展性而受到程序员的青睐。

2302_79376097的博客 3827

Spring Boot 实现多图片上传并回显,涨姿势了~

上传 Controller的代码非常简单,由于用了SpringMVC框架,所以直接用MultipartFile来接即可。由于是多图片上传所以用数组来接。此处应该注意参数名应该和<input>中的name值相对应: @RequestMapping("/pic") @ResponseBody publicResponseEntity<String>pic(MultipartFile[]pictures)throwsException{ ResponseEnti...

weixin_54556126的博客 894

C++的认识

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Mar

qq_57916989的博客 1315

V.PhyloMaker实战:从物种列表到维管束植物系统发育树的完整流程

本文详细介绍了使用V.PhyloMaker工具包,从物种列表快速构建维管束植物系统发育树的完整实战流程。内容涵盖R包安装、物种名标准化、核心函数phylo.maker的三种构建方案选择、结果树的可视化与导出,以及与picante包的联动分析,为生态学和生物地理学研究提供了高效解决方案。

weixin_29057237的博客 379

python实现ECMS算法

ECMS(Equivalent Consumption Minimization Strategy)算法是一种用于混合动力汽车能量管理系统的优化策略。它通过计算等效油耗来平衡电池电量消耗和燃油消耗,从而优化整体能耗。以下是一个简单的Python实现,用于演示ECMS算法的基本思想。这个实现假设了一个简单的混合动力汽车模型,其中电池电量和燃油消耗是主要的优化目标。

weixin_45570158的博客 923

C++的初步认识

C++

weixin_67207358的博客 986

Qt 侧边菜单栏+堆叠窗口stackedWidget

效果如下:环境:Qt 6.6.2 MSVC2019 64bit。

weixin_41033231的博客 1568

对c++的认识

新年快乐,大家好,刚刚结束了一个学期紧张的c++的学习生活,虽然忙碌,但是也很充实,不过,初识c++,难免有些困惑和疑惑,在这里也不知道说些什么,只能聊一下自己对于电脑和c++的认识。   c++是一个编程语言,也是所有软件的基础,电脑可以根据你的编程语言执行命令去完成作者想要并且打算完成的任务的编程语言。而c++也是现在社会发展最广泛最使用的最稳定的得到广大群众认可的一种编程语言。   c+

u013766847的专栏 1070

观测器选择与工程实践建议

摘要:永磁同步电机(PMSM)无传感器控制中,观测器选型需综合考虑应用场景、性能需求与成本。消费级(家电、工具)推荐滑模观测器(SMO),成本低、鲁棒性强;工业级(伺服、泵阀)适用扩展卡尔曼滤波器(EKF),精度高但计算复杂;车规级(EPS、主驱动)需混合观测器(SMO+EKF),兼顾全速域性能与可靠性。低速时需高频注入法,IPMSM更适用。SMO易实现但存在抖振,EKF调试复杂。未来趋势是混合架构与AI增强,提升适应性与性能。选型需权衡速度范围、电机类型、处理器能力及成本。

汽车软件开发 146

2024美团秋招硬件开发笔试真题及答案解析

在 Linux 内核的网络设备驱动中,数据链路层的功能通常由网络协议栈的低层(如以太网驱动)实现,而不是作为网络设备驱动的一个独立层次。在 FreeRTOS 中,任务通知(Task Notifications)是一种轻量级的事件传递机制,用于在任务之间或任务与中断之间传递信号。小美正在开发一个简单的密码生成器,其中一个功能是将输入的字符串中的所有字母按字母顺序循环前移一位(即 'a' 变为 'z','B' 变为 'A',以此类推)。它包含了网络设备的各种参数和方法,用于管理网络设备的初始化、配置和操作。

XU157303764的博客 1678

对C++的认识

我又孤陋寡闻了一次!我和优快云的博友在讨论C++不如Java的原因时搬出了很多年前stroustrup说的观点,和Java相比,C++的framework急需发展。这几年关注的开源项目主要集中在Java世界,C++方面仍然仅仅局限在几个经典项目上,比如ACE,Loki,Boost。今天偶然在stackoverflow上查阅了一下,居然得到了不小的惊喜:1.staff Restful web se

风尘璞的博客 721

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Effective C++ 2e Item5

内存管理C++中涉及到的内存的管理问题可以归结为两方面:正确地得到它和有效地使用它。好的程序员会理解这两个问题为什么要以这样的顺序列出。因为执行得再快、体积再小的程序如果它不按你所想象地那样去执行,那也一点用处都没有。“正确地得到”的意思是正确地调用内存分配和释放程序;而“有效地使用”是指写特定版本的内存分配和释放程序。这里,“正确地得到”显得更重要一些。然而说到正确性,C++其实从C继承

lostmouse的专栏 1199

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Effective C++ 2e Item1

 从C转向C++对每个人来说,习惯C++需要一些时间,对于已经熟悉C的程序员来说,这个过程尤其令人苦恼。因为C是C++的子集,所有的C的技术都可以继续使用,但很多用起来又不太合适。例如,C++程序员会认为指针的指针看起来很古怪,他们会问:为什么不用指针的引用来代替呢?C是一种简单的语言。它真正提供的只有有宏、指针、结构、数组和函数。不管什么问题,C都靠宏、指针、结构、数组和函数来解决。而C

lostmouse的专栏 1488

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Effective C++ 2e Item7

条款7:预先准备好内存不够的情况operator new在无法完成内存分配请求时会抛出异常(以前的做法一般是返回0,一些旧一点的编译器还这么做。你愿意的话也可以把你的编译器设置成这样。关于这个话题我将推迟到本条款的结尾处讨论)。大家都知道,处理内存不够所产生的异常真可以算得上是个道德上的行为,但实际做起来又会象刀架在脖子上那样痛苦。所以,你有时会不去管它,也许一直没去管它。但你心里一定还是深深

lostmouse的专栏 1668

Effective C++ 2e Item44

条款44: 说你想说的;理解你所说的在本章关于 "继承和面向对象设计" 的简介中,我曾强调,理解不同的面向对象构件在C++中的含义十分重要。这和仅仅知道C++语言的规则有很大的不同。例如,C++规则说,如果类D从类B公有继承,从D的指针到B的指针就有一个标准转换;B的公有成员函数将被继承为D的公有成员函数,等等。这些规则都是正确的,但在将设计思想转化为C++的过程中,它们起不到任何作用。相反,

lostmouse的专栏 1148

Effective C++ 2e Item33

条款33: 明智地使用内联内联函数------多妙的主意啊!它们看起来象函数,运作起来象函数,比宏(macro)要好得多(参见条款1),使用时还不需要承担函数调用的开销。你还能对它们要求更多吗?然而,你从它们得到的确实比你想象的要多,因为避免函数调用的开销仅仅是问题的一个方面。为了处理那些没有函数调用的代码,编译器优化程序本身进行了专门的设计。所以当内联一个函数时,编译器可以对函数体执行特

lostmouse的专栏 1141

Effective C++ 2e Item15

条款15: 让operator=返回*this的引用C++的设计者Bjarne Stroustrup下了很大的功夫想使用户自定义类型尽可能地和固定类型的工作方式相似。这就是为什么你可以重载运算符,写类型转换函数(见条款M5),控制赋值和拷贝构造函数,等等。他做了这么多努力,那你最少也该继续做下去。让我们看看赋值。用固定类型的情况下,赋值操作可以象下面这样链起来:int w, x, y,

lostmouse的专栏 1079

Effective C++ 2e Item30

条款30: 避免这样的成员函数:其返回值是指向成员的非const指针或引用,但成员的访问级比这个函数要低使一个成员为private或protected的原因是想限制对它的访问,对吗?劳累的编译器要费九牛二虎之力来确保你设置的访问限制不被破坏,对不对?所以,写个函数来让用户随意地访问受限的成员没多大意义,对不对?如果你确实认为有意义,那么请反复阅读本段,直到你不这样认为为止。实际编程中很容易

lostmouse的专栏 1627

Effective C++ 2e Item4

条款4:尽量使用C++风格的注释旧的C注释语法在C++里还可以用,C++新发明的行尾注释语法也有其过人之处。例如下面这种情形:    if ( a > b ) {      // int temp = a;    // swap a and b      // a = b;      // b = temp;    }假设你出于某种原因要注释掉这个代码块。从软件工程的角度看,写这段代码的程

lostmouse的专栏 1080

Effective C++ 2e Item24

条款24: 在函数重载和设定参数缺省值间慎重选择会对函数重载和设定参数缺省值产生混淆的原因在于,它们都允许一个函数以多种方式被调用:void f();                             // f被重载void f(int x);f();                                  // 调用f()f(10);                 

lostmouse的专栏 1012

Effective C++ 2e Item31

条款31: 千万不要返回局部对象的引用,也不要返回函数内部用new初始化的指针的引用本条款听起来很复杂,其实不然。它只是一个很简单的道理,真的,相信我。先看第一种情况:返回一个局部对象的引用。它的问题在于,局部对象 ----- 顾名思义 ---- 仅仅是局部的。也就是说,局部对象是在被定义时创建,在离开生命空间时被销毁的。所谓生命空间,是指它们所在的函数体。当函数返回时,程序的控制离开了这

lostmouse的专栏 1058

Effective C++ 2e Item10

 条款10. 如果写了operator new就要同时写operator delete让我们回过头去看看这样一个基本问题:为什么有必要写自己的operator new和operator delete?答案通常是:为了效率。缺省的operator new和operator delete具有非常好的通用性,它的这种灵活性也使得在某些特定的场合下,可以进一步改善它的性能。尤其在那些需要动态分

lostmouse的专栏 1190

Effective C++ 2e Item28

条款28: 划分全局名字空间全局空间最大的问题在于它本身仅有一个。在大的软件项目中,经常会有不少人把他们定义的名字都放在这个单一的空间中,从而不可避免地导致名字冲突。例如,假设library1.h定义了一些常量,其中包括:const double LIB_VERSION = 1.204;类似的,library2.h也定义了:const int LIB_VERSION = 3;很

lostmouse的专栏 1076

Effective C++ 2e Item8

条款8. 写operator new和operator delete时要遵循常规自己重写operator new时(条款10解释了为什么有时要重写它),很重要的一点是函数提供的行为要和系统缺省的operator new一致。实际做起来也就是:要有正确的返回值;可用内存不够时要调用出错处理函数(见条款7);处理好0字节内存请求的情况。此外,还要避免不小心隐藏了标准形式的new,不过这是条款9的话

lostmouse的专栏 1123

Effective C++ 2e Item18

类和函数:设计与声明在程序中声明一个新类将导致产生一种新的类型:类的设计就是类型设计。可能你对类型设计没有太多经验,因为大多数语言没有为你提供实践的机会。在C++中,这却是很基本的特性,不是因为你想去做才可以这么做,而是因为每次你声明一个类的时候实际上就在做,无论你想不想做。设计一个好的类很具有挑战性,因为设计好的类型很具有挑战性。好的类型具有自然的语法,直观的语义和高效的实现。在C++中

lostmouse的专栏 1010
上一篇: Effective C++ 2e Item49
下一篇: CUJ C++ Experts Forum: conversation (September 2001)
lostmouse
博客等级 码龄26年 22粉丝 63原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值