<More Effective C++>笔记--技巧

Purify使用指南 1. 简介2. 安装2.1. 安装license2.2. 安装Purify3. 使用3.1. 查看帮助3.2. 使用步骤   ATTACH3.3. 查看BUG   ATTACH3.4. 定位BUG在源代码中的位置   ATTACH3.5. 查找泄漏的内存   ATTACH3.6. 修改BUG   ATTACH3.7. 隐藏消息   ATTACH4. 保存/载入结果4.1. 保存结果4.2. 载入结 阅读详情

4 技巧
~~~~~~~

4.1 如何将构造函数和非成员函数虚拟化
=====================================
   1. 虚拟构造函数是指能够根据输入给它的数据的不同而建立不同类型的对象的成员函数(不是构造函数!!).
   2. 虚拟拷贝构造函数返回一个指针,指向调用该函数的对象的新拷贝.因此其名字通常为clone()
   3. 被派生类重定义的虚拟函数不用必须与基类的虚拟函数具有一样的返回类型:
      如果函数的返回类型是一个指向基类的指针(或一个引用),那么派生类的函数可以返回一个指向基类的派生类的指针(或引用)
   4. 根据参数的不同动态类型而行为特征也不同的非成员函数叫做虚拟化的非成员函数
   5. 虚拟化的非成员函数实际上也是通过参数中的成员函数来实现的.

4.2 如何限制某个类能产生的对象数量
===================================
   1. 在类中的静态对象总是被构造和释放的,及时不使用该对象.
      函数中的静态对象只有在第一次执行函数时才会建立对象.
   2. 我们能够准确地知道函数的静态成员在第一次执行定义静态成员的函数时初始化.
      而无法定义一个类的静态成员被初始化的时间.
   3. 带有内部链接的函数可能在程序内被复制,这种复制也包含函数内的静态对象.
      因此如果建立一个包含局部静态对象的非成员内联函数,你可能使程序的静态对象的拷贝超过一个.
      所以,不要建立包含局部静态对象的非成员函数的内联函数.
   4. 可以在public:中使用using语句using private函数,这样可以把private函数恢复public访问权限.

4.3 如何要求/禁止在堆中产生对象
================================

4.3.1 要求在堆中建立对象
-------------------------
    1. 非堆函数在定义它的地方被自动构造,在生存时间结束时自动释放,所以要禁止使用隐式的构造函数和析构函数就可以实现这种只能通过new手段建立对象的限制了.
       最好让析构函数成为private(结果是该类不能被继承)或protected(该类可以被继承),让构造函数成为public.
       你可以引进一个专用的伪析构函数,用来访问真正的析构函数.客户端调用伪析构函数释放他们建立的对象.(注意,异常处理体系要求所有在栈中的对象的析构函数必须申明为公有!)
 

 
  1. class A 
  2. { 
  3. public: 
  4.     void destory()const {delete this;}  //伪析构函数 
  5. private: 
  6.     ~A(){} 
  7. }; 
  8. int main() 
  9. { 
  10.     //A a;             //编译出错 error: 'A::~A()' is private 
  11.     A* a = new A();    //能编译通过 
  12.     //delete a           //错误,~A() is private 
  13.     a->destory;          //正确,通过调用伪析构函数,访问真正的析构函数. 
  14. } 



4.3.2 判断对象是否在堆中.
--------------------------
    1. 在new一个数组时,只会调用一个operator new[],执行多次构造函数.因此不能通过在operator new和operator new[]中设置成员变量的方式来判断对象是否在堆中.
    2. 静态对象可能分配在堆中也可能分配在栈中,它们的位置依据系统而定.
    3. 我们可以通过抽象混合(mixin)基类给派生类提供判断指针指向的内存是否由operator new分配的能力.

4.3.3 禁止堆对象
-----------------
    1. 禁止对象在堆中直接实例化
       由于new操作符总是调用operator new函数,因此可以自己声明operator new函数,并把它作为private权限.
    2. 禁止对象作为派生类的基类在堆中实例化
       如果operator new和operator delete没有在派生类中进行声明,它们就会继承基类中的版本,因此,基类中声明了private的operator new和operator delete,也能阻碍类作为一个位于堆中的派生类对象的基类被初始化.
       如果派生类声明它自己的operator new,当在堆中分配派生对象时,就会调用自己的operator new函数.这就得另找一个不同的方法来防止基类的分配问题.
    3. 对象被嵌入到其他对象内,在堆中实例化
       类的operator new是private这一点,不会对包含该类对象的对象分配产生任何影响.

4.4 智能指针
=============
   1. 因为当调用auto_ptr的拷贝构造函数时,对象的所有权被传递出去,所以通过传值方式传递auto_ptr对象是一个很糟糕的方法.
   2. T& operator*()的返回值需要设置为reference
   3. 一个智能指针如果提供了默认转换为原始指针,则可能出现delete smart_ptr<T>的写法,这样会导致一个对象指针被delete两次.
      因此除非有必要,否则尽量不要提供转换到原始指针的隐式类型转换符.

4.4.1 智能指针和基础类到基类的类型转换
---------------------------------------
    1. smart_ptr<Base>和smart_ptr<Sub>之间并无任何关系,不能认为这两个智能指针之间存在继承关系.
       1) 但是可以通过在smart_ptr<Sub>中定义隐式类型转换符operator smart_ptr<Base>的方式,模拟子类与基类指针之间的转换.
          这个方法有两个缺点:一,你必须认为特化smart_ptr<Sub>,这就破坏了模板的通用性.二,你可能必须添加许多类型转换符,因为你的对象可能位于继承层次中很深得位置.
       2) 声明(非虚)成员函数模板(成员模板),使用它来生成灵巧指针类型转换函数.它的原理与第一种方法一样的
 

 
  1. template<class newType> 
  2. operator Smart_ptr<newType>() 
  3. { 
  4.     return Smart_ptr<newType>(m_pointee); 
  5. } 


          这种方法也有个缺点,如果定义了函数Func(Smart_Ptr<Base>)和Func(Smart_Ptr<Sub>),那么对于Sub的子类SubSub,调用Func(Smart_Ptr<SubSub>)具有二义性,不知道把它转换为Smart_Ptr<Base>还是Smart_Ptr<Sub>
       3) 综上所述,无法让智能指针的行为与原始指针一样.最好的方法是使用成员模板生成类型转换函数,在会产生二义性结果的地方使用casts

4.4.2 智能指针和const
----------------------
    1. 由于智能指针实质上只是一个类,所以const smart_ptr<C>表示智能指针中的pointee是不能变的.
       要表示智能指针指向一个const对象,需要定义为smart_ptr<const C>.
    2. 由于smart_ptr<C>和smart_ptr<const C>是两个完全不同的类型,因此不能用smart_ptr<C>初始化smart_ptr<const C>
    3. 由于const和non-const指针有类似于父类与子类的关系,因此可以考虑通过继承的方式实现smart_ptr和const_smart_ptr
 

 
  1. const_smart_ptr<T> 
  2. { 
  3.      const T* cpt; 
  4. } 
  5. smart_ptr<T>::public const_smart_ptr<T> 
  6. { 
  7.     T* pt 
  8. } 


4.5 引用计数
=============

4.6 代理类
===========
   1. const函数的调用与否,与其返回值是作为左值还是右值无关,而仅仅与调用成员函数的对象的const属性有关.
   2. operator[]无法判断其返回值会被用于左值还是右值,这是可以实现一个代理类,在该代理类中包含原类的一个引用,当对代理类写时就可以对原对象做个拷贝.

4.7 让函数根据一个以上的对象来决定怎么虚拟
===========================================
   1. 无名命名空间的东西是当前编译单元(其实就是当前文件)私有,这很像文件范围内的static函数一样,有了命名空间之后,文件范围的static已经不赞成使用了.
   2.

本文出自 “暗日” 博客,请务必保留此出处http://darksun.blog.51cto.com/3874064/1162478

Java 大视界 -- Java+Spark MLlib 构建智能推荐系统:协同过滤算法实战与优化(441) Java+Spark MLlib构建智能推荐系统实战 本文详细介绍了基于Java和Spark MLlib构建协同过滤推荐系统的全流程实践方案。主要内容包括: 架构设计:采用离线批处理为主、近实时更新为辅的架构,包含数据采集层、处理层、模型层、推荐生成层、存储层和应用层六大模块,可支撑千万级用户推荐需求。 技术实现: 使用Spark MLlib的ALS算法进行协同过滤模型训练 提供数据清洗、模型训练、推荐生成等核心代码实现 采用MySQL存储推荐结果,支持批量插入和事务保障 生产级优化: 版本化模型存储规避覆 阅读详情

相关推荐

数字麦克风PDM信号采集与STM32 I2S接口应用(二)

在使用STM32的数字麦克风I2S接口时,计算采样率让人头疼,芯片手册上没有明确的说法,而手册上的计算方法经过测试却和实验不符。借助搜索引擎,大部分资料都是来自于开发板卖家或开发板论坛,主要是咪头采集然后配置WM89系列解码芯片,然后配合FatFS、MP3解码等模式,主要是讲解I2S录音、存储、放音等。外文资料得到的也寥寥无几,也没有找到讲解STM32数字麦克风配置、计算的文档。加上网上资料转载、抄袭、浅尝辄止的笔记教程,这些更是让检索大海捞针,过程艰辛一言难尽,有些网文三言两语抑或作者都没有搞清楚随手一写

XIAOYOUDUODUO的博客 6055

<More Effective C++>笔记--技巧

4 技巧 ~~~~~~~ 4.1 如何将构造函数和非成员函数虚拟化 ===================================== 1. 虚拟构造函数是指能够根据输入给它的数据的不同而建立不同类型的对象的成员函数(不是构造函数!!). 2. 虚拟拷贝构造函数返回一个指针,指向调用该函数的对象的新拷贝.因此其名字通常为clone() ...

weixin_34113237的博客 146

YOLOv8_obb的C++工程部署实战:从模型转换到实时视频推理

本文详细介绍了YOLOv8_obb模型在C++环境下的完整工程部署流程,涵盖从PyTorch模型到ONNX格式的转换、基于ONNX Runtime的C++推理引擎搭建、旋转框后处理解析,以及实时视频流处理与性能优化。文章重点解析了模型转换的关键参数、环境配置的常见问题、核心推理代码的实现,并提供了实用的避坑指南,旨在帮助开发者高效完成YOLOv8_obb的C++工程部署。

weixin_29100927的博客 45

More Effective C++ 阅读笔记 解释清晰

More Effective C++ 阅读笔记 解释清晰

哇咔咔的博客 963

Python读取三菱PLC数据

3、支持自定义的数据读写操作。直接调用Read方法,可以读取到原生的byte数组,然后进行组合数据。1、每次的数据交互您都可以判断是否成功,如果您不判断,如果网络断开或是异常,会影响程序的执行。Qna3E协议的ascii类 MelsecMcAsciiNet。A兼容1E协议的二进制类 MelsecA1ENet。Qna3E协议的二进制类 MelsecMcNet。2、读写操作支持单个数和数组。

weixin_46744807的博客 1998

PP生产订单的BADI增强 WORKORDER_UPDATE

我们的项目需求是: 1、 保存时检查工单BOM是否存在物料号相同的行项目,如果有则提示“物料& 重复,请检查工单BOM” 系统增强出口:PPCO0001,检查组件行项目是否有重复物料项 开始以为的增强增强看一下是用PPCO0001还是PPCO0007 后来找到了badi WORKORDER_UPDATE IF_EX_WORKORDER_UPDATE~BEFORE_UPDATE

ERP运维咨询(目标和成功) 4636

<<More Effective C++>>读书笔记5: 技巧(1)

《More Effective C++》+《Effective C++》,两本经典双剑合璧,必然威力无穷。         《More Effective C++》的第5章约占全书的45%,是全书最难的部分,有些地方看的人很晕,但大多会让人心悦诚服;大多的技巧都不局限于C++,可应用于所有语言的编程思想。     为了便于消化,我将这一章分为两部分来阅读。            Item

Lemon 942

STM32实现webserver显示数据及配置参数

其实提到的将fsdata.c重命名为fsdata_custom.c,可以不重命令,将/LWIP/Target/lwipopts.h中HTTPD_USE_CUSTOM_FSDATA 定义为0,这样HTTPD_FSDATA_FILE将使用fsdata.c,避免每次生成fsdata.c需要重命令的麻烦。2、登录成功后,板卡根据板卡配置类型,返回对应的数据页面,该页面可实现数据校准、清零,以及进行到板卡参数设置页面。目前还未实现post功能以及http身份验证功能。3、板卡参数设置页面。

2694

MoreEffectiveC++笔记 7技巧

MoreEffectiveC++笔记 7技巧1构造函数和非成员函数虚拟化2限制某个类能产生的对象数目3要求或禁止在堆上生成对象4灵巧指针(智能指针) 1构造函数和非成员函数虚拟化 虚拟构造函数不是指把构造函数用virtual修饰。对象没有构造完成,不会产生多态的效果。这里是说构造函数调用一个工厂函数,产生的对象会作为这个类的成员,工厂函数会根据输入参数的不同动态生成不同的子类(因为能生成不同类型子类对象所以书里面叫他虚拟构造函数)。类似的可以定义虚函数clone作为虚拟拷贝构造函数完成多态复制。 虚拟化非成

GuoSheng的博客 323

飞书云文档API实战:从权限申请到自动化操作

本文详细介绍了飞书云文档API的实战应用,从权限申请到自动化操作。内容涵盖如何创建应用、获取关键API权限、理解并使用Tenant Access Token,并通过Python代码示例演示了读取和写入飞书表格数据的具体方法,旨在帮助开发者和业务人员实现文档数据处理的自动化,提升工作效率。

weixin_28318011的博客 1942

学Simulink——基于软开关与高频变换的整流器系统场景实例:移相全桥ZVS整流器在轻载条件下的效率优化

本文以Simulink为平台,详细介绍了移相全桥ZVS整流器在轻载条件下的建模与优化方法。通过六个步骤系统讲解了从项目创建到仿真运行的全过程,重点分析了移相全桥拓扑结构、ZVS检测逻辑设计及轻载特性。结果显示,传统移相全桥在轻载时ZVS失效导致效率下降(<88%)。针对此问题,提出了动态频率调整、不对称半桥模式等优化策略。该案例为理解软开关技术、提升电源效率提供了实用建模方法和优化思路。

xiaoheshang_123的博客 117

&lt;More Effective C++&gt;笔记--其他杂项

5 其他杂项 ~~~~~~~~~~~ 5.1 在未来时态下开发程序 =========================    1. 用C++语言自己来表达设计上的约束条件,而不是用注释或文档    2. 未来时态的考虑不是问一个类现在正被怎么使用,而是问这个类是被设计为怎么去使用的.    3. 未来时态的考虑只是简单地增加了一些额外约束:       * 提供完备的类,即

暗日 406

PCL DBSCAN密度聚类【2026最新版】

点云密度聚类的PCL代码实现,与matlab自带的密度聚类算法进行对比验证,结果一致。3万多个点能再2秒左右运行出结果,算法效率尚可。

点云侠的博客 5682

&lt;More Effective C++&gt;笔记--异常

3 异常 ~~~~~~~ 3.1 防止构造函数在存在异常时发生资源泄露 =========================================    1. 如果你用对应的auto_ptr对象替代指针成员变量,就可以防止构造函数在存在异常时发生资源泄漏,你也不用手工在析构函数中释放资源,并且你还能象以前使用非const指针一样使用const指针,给其赋值。 3.2

暗日 389

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

&lt;More Effective C++&gt;笔记--运算符

2 运算符 ~~~~~~~~~ 2.1 谨慎定义类型转换函数 =========================    1. 有两种函数允许编译器进行隐式类型转换:       * 单参数构造函数(包括除了第一个参数,所有参数都有缺省值得情况)       * 隐式类型转换运算符         隐式类型转换运算符只是一个样子奇怪的成员函数:operator 关键字,其后跟一

暗日 337

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

&lt;More Effective C++&gt;笔记--基础

1 基础 ~~~~~~~ 1.1 指针和引用区别 ===================    1. 指针可以指向空值,引用不能指向空值    2. 指针定义时可以不初始化,引用定义时必须初始化    3. 指针可以被重新赋值指向另一个对象,而引用在初始化时被指定的对象,以后不能改变,但它和本体的值会因赋值而改变    4. 如果你需要重载一个操作符时,应该使用引用 1

暗日 373

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

在类的头文件里尽量少引入其它头文件 &lt;&lt;Effective Objective-C&gt;&gt;

与C 和C++ 一样,Objective-C 也使用“头文件”(header file) 与“实现文件”(implementation file)来区隔代码。用Objective-C 语言编写“类”(class)的标准方式为:以类名做文件名称,分别创建两个文件,头文件后缀用.h,实现文件后缀用.m。创建好一个类之后,其代码看上去例如以下所看到的: // EOCPe...

weixin_30609287的博客 102

读书笔记:Effective C++ 2.0 版,条款19(成员函数,非成员函数和友元函数)

条款19: 分清成员函数,非成员函数和友元函数

weixin_43172531的博客 122

Effective c++ 条款19: 分清成员函数,非成员函数和友元函数

本条款得出如下结论: 假设f是想正确声明的函数,C是和它相关的类: 1.虚函数必须是成员函数。如果f必须是虚函数,就让它成为C的成员函数。 2.operator&gt;&gt;和operator&lt;&lt;决不能是成员函数。如果f是operator&gt;&gt;或operator&lt;&lt;,让f成为非成员函数。如果f还需要访问C的非公有成员,让f成为C的友元函数。 3.只有非成...

weixin_30848775的博客 126

cppcheck使用指南

cppcheck使用指南Table of Contents1 cppcheck简介2 cppcheck使用3 cppcheck与其他软件的整合3.1 与VisualStudio的配合3.2 与TortoiseSVN配合1 cppcheck简介cppcheck是一个静态代码检查工具,支持c/ c++代码;作为编译器的一种补充检查,cppcheck对产品的源代码执行严格的逻辑检查。执行的检查包括:自动

暗日 1万+

当用fopen读写打开文件时,请使用r+,而不是rw

C++标准中fopen函数的mode只有r,r+,w+,a,a+这几种类别,而没有rw这种类别. 如果尝试对用rw方式打开文件进行写操作,不同的编译器会有不同的处理方式.例如在linux下用gcc4.6.3把rw当成r来处理,会提示bad file descriptor在windows下用dev C++则只是将写文件函数返回失败,但是没有设置errno根据百度百科的说明,还有些编译器则能够把rw识

暗日 5081

为子shell设置变量值的两种方法

为子shell设置变量值有两种方法:一种很常见的方法是将变量export成环境变量,这样该变量就会被带到子shell中去了echo 'echo x=$x' > /tmp/echox chmod +x /tmp/echox x=Hi echo "x不是环境变量的情况下" /tmp/echox echo "x是环境变量的情况下" export x /tmp/echoxx不是环境变量的情况下 x= x是环

暗日 4252

《WebSphereMQ基础教程》MQI笔记

一、MQI的基本数据类型 数据类型 <td width="477" valign="top" style="width:357.7pt;border:solid windowtext 1.0pt; border-left:none

暗日 3171

shell中| ; &的优先级

| 的优先级要高于 ;date; who |wc 2016年 11月 14日 星期一 22:18:38 CST 1 5 45你会发现只有who的结果送到了wc命令. 括号可以用来组合命令(date;who) |wc 2 11 88date与who的结果都送到了wc命令 & 的优先级高于 ;date sleep 5;date & date 201

暗日 2333

《Python网络编程基础》笔记

python网络编程基础                           ================== Author: lujun9972 Date: 2013-03-08 22:29:20 CST Table of Contents ================= 1 客户端与服务器端     1.1 使用inetd或xinetd     1.2

暗日 1764

lua与javascript的相似之处

1. lua中的table,类似于javascript中的Array(数组,同时也是Object,可以当Map用) address={1,2,3} address.Street="Wyman Street" address.Contry="USA" print(address.Street,address["Contry"]  2. 与javascript类似,所有的变量默认为全局变量.lua

暗日 1739
上一篇: &lt;More Effective C++&gt;笔记--异常
下一篇: &lt;More Effective C++&gt;笔记--其他杂项
darksun9972
博客等级 码龄19年 42粉丝 399原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值