
More Effective C++
白话机器学习
10年IT从业经验,人工智能高级算法工程师、优快云博客专家、阿里云专家、《2023博客之星马龄赛道11-15年》第一名、《2023博客之星,城市赛道》长春TOP1,优快云付费资源项目实践专家
展开
-
关于More Effective C++类别中的博文内容的一些声明
More Effective C++ 这个类别中的所有博文的内容均是本人整理自More Effective C++这本书。作为自己在C++的学习道路上的一些积累,意在方便自己和大家一起学习查阅。博文内容最终解释权均归More Effective C++原著作者所有,在这里只是摘抄记录方便学习交流。在这里感谢原著作者大牛 Scott Meyers,还有原著的翻译们的辛勤工作。感谢他们的工原创 2013-05-18 11:05:09 · 728 阅读 · 0 评论 -
7.使用析构函数防止资源泄露
对指针说再见。必须得承认:你永远都不会喜欢使用指针。Ok,你不用对所有的指针说再见,但是你需要对用来操纵局部资源(local resources)的指针说再见。假设,你正在为一个小动物收容所编写软件,小动物收容所是一个帮助小狗小猫寻找主人的组织。每天收容所建立一个文件,包含当天它所管理的收容动物的资料信息,你的工作是写一个程序读出这些文件然后对每个收容动物进行适当的处理(appropriate原创 2013-05-10 16:55:25 · 767 阅读 · 0 评论 -
15.如何在同一个程序中混合使用C++和C
如何在同一个程序中混合使用C++和C1.名变换名变换,就是C++编译器给程序的每个函数换一个独一无二的名字。由函数名和参数组合生成一个新的名字,这样为了支持函数重载在C语言中,这样的做法是不必要的,因为它没有重载函数。这样就存在一个问题:就是当你在C++环境中调用C函数库中的函数时,比如一个drawLine(int x,int y)。经过C++编译器后在obj中的函数名称可能是原创 2013-05-23 19:13:38 · 1204 阅读 · 1 评论 -
6.了解异常处理的系统开销
为了在运行时处理异常,程序要记录大量的信息。无论执行到什么地方,程序都必须能够识别出如果在此处抛出异常的话,将要被释放哪一个对象;程序必须知道每一个入口点,以便从try块中退出;对于每一个try块,他们都必须跟踪与其相关的catch子句以及这些catch子句能够捕获的异常类型。这种信息的记录不是没有代价的。虽然确保程序满足异常规格不需要运行时的比较(runtime comparisons),而且当原创 2013-05-10 14:21:54 · 1058 阅读 · 0 评论 -
5.理解“抛出一个异常”,“传递一个参数”和“调用一个虚函数”间的差异
从语法上看,在函数里声明参数和在catch子句中声明参数几乎没什么区别。class Widget { ... }; //一个类,具体是什么类// 在这里并不重要void f1(Widget w); // 一些函数,其参数分别为void f2(Widget& w); // Widget, Widget&,或void f3(const Widget& w); // Widget*原创 2013-05-10 14:20:48 · 879 阅读 · 0 评论 -
14.智能(smart)指针,实现细节
它本质上是一个对象,但是被设计成使用方法和外观都和内建指针相似。智能指针是从模板中生成的,模板的参数确定指向的对象类型。大部分智能指针的模板看起来可能会是这样:templateclass SmartPtr {public:SmartPtr(T* realPtr = 0); // 建立一个智能指针// 指向dumb pointer所指的对象。未初始化的指针,缺省值为0(null)原创 2013-05-22 16:52:11 · 1169 阅读 · 0 评论 -
13.如何做到要求或禁止在堆中产生你自定义的对象
如果你的程序要在嵌入式系统上工作,发生在嵌入式系统上的内存泄露是非常严重的,它的堆空间是非常珍贵的。有没有可能编写出来的代码要求或禁止在堆中产生对象呢。通常是可以的。1.要求在堆中建立对象意思就是我们必须调用new才能创建一个对象,非堆对象在定义它的地方被自动构造,在生存时间结束时自动被释放,所以只要禁止使用隐式构造函数和析构函数,就可以实现这种限制。最简单的方法就是将构造函数和析构函原创 2013-05-22 10:39:43 · 734 阅读 · 0 评论 -
10.限制某个类所能产生的对象数量——之一
某些情况下你需要限制某个类所能产生的对象的数量,例如你在系统中只有一台打印机,所以你想用某种方式把打印机对象数目限定为一个。或者你仅仅取得16个可分发出去的文件描述符,所以应该确保文件描述符对象存在的数目不能超过16个。你如何能够做到这些呢?如何去限制对象的数量呢?首先如何能够彻底阻止某个对象的实例化呢?每次实例化一个对象时,我们很确切地知道一件事情:“将调用一个构造函数。”事实确实这原创 2013-05-16 16:59:03 · 1188 阅读 · 0 评论 -
9.深刻理解临时对象的来源
一般我们经常把仅仅需要一小段时间的变量成为临时变量。例如在一个swap(交换)程序中templatevoid swap(T& obj1,T& obj2){ T tmp=obj1; obj1=obj2; obj2=tmp;}通常把temp叫做临时变量。不过就C++而言,temp根本不是临时变量,它只是一个函数的局部对象。在C++中真正的临时对象是看不见的,它们不出现在你的源代码中原创 2013-05-16 10:53:40 · 795 阅读 · 0 评论 -
12.30分钟搞定虚函数,多继承,虚基类和RTTI
C++的语言特性是由编译器来实现的,实现细节也由编译器来决定,对于不同的编译器,对语言特性的实现可能也不尽相同。虽然在大多数情况下,你是不用关心他们具体是如何实现的,但是有些特性的实现,对对象的大小和成员函数执行速度有很大影响,所以我们有必要了解一下编译器在背后为我们做了些什么。1.虚函数当调用一个虚拟函数时,被执行的代码必须与调用函数的对象的动态类型相一致;指向对象的指针或引用的类型是不原创 2013-05-18 17:29:35 · 1310 阅读 · 0 评论 -
11.限制某个类所能产生的对象数量——之二
一个具有对象计数功能的基类如果我们有大量像Printer需要限制实例数量的类,就必须一遍又一遍地编写一样的代码,每个类编写一次。这将会使大脑变得麻木。应该有一种方法能够自动处理这些事情。难道没有方法把实例计数的思想封装在一个类里吗?我们很容易地能够编写一个具有实例计数功能的基类,然后让像Printer这样的类从该基类继承,而且我们能做得更好。我们使用一种方法封装全部的计数功能,不但封装维护原创 2013-05-16 20:16:37 · 579 阅读 · 0 评论 -
8.将构造函数和非成员函数“虚拟化”
在讨论内容之前先看下面的一个程序,它用来进行新闻报道工作,每一条新闻报道都由文字或图片组成。class NLComponent { //用于 newsletter componentspublic: // 的抽象基类... //包含至少一个纯虚函数};class TextBlock: public NLComponent {public:... // 不包含纯虚函数};clas原创 2013-05-16 10:17:09 · 762 阅读 · 0 评论 -
4.通过引用捕获异常
跟给函数传递参数一样,有三种选择可以让异常传递到catch子句里。分别是通过指针,传值,和引用。1.通过指针方式捕获异常:理论上来说这种方法的实现对于throw传递异常到catch子句中来说是效率最高的。因为在传递异常信息时,只有采用通过指针抛出异常的方法才能做到不拷贝对象。class exception{...} //C++标准库(STL)中的异常层次类void someFunc原创 2013-05-07 20:25:27 · 1173 阅读 · 0 评论 -
3.自增自减操作符前缀形式与后缀形式的区别
C++允许重载自增,自减操作符。重载函数间的区别取决于它们的参数类型上的差异。C++规定后缀形式有一个int类型的参数,当函数被调用时,编译器传递一个0做为int参数的值给该函数。class UPInt{public:UPInt& operator++(); //++前缀重载形式cosnt UPInt operator++(int);//++后缀重载形式UPInt原创 2013-05-07 19:28:18 · 1459 阅读 · 0 评论 -
2.尽量使用C++风格的类型转换
C风格的类型转换时一种极其粗鲁的转换,允许你在任何类型间进行转换,转换过程中存在很大的风险,编译器难检查出错误。例如:1.把一个const指针转换成非const指针2.将一个指向基类型的指针转换成指向子类型的指针在C风格中的转换跟本不会对这些不同情况进行区分,原因也很简单,因为C风格转换时为C语言设计的,所以不可能考虑C++的感受。在一个是C风格的转换从语法上来说不好识别(ty原创 2013-05-07 11:16:22 · 781 阅读 · 0 评论 -
1.指针与引用的区别
指针和引用看上去似乎完全不同,指针操作时使用"*"和"->"操作符,而引用使用“.”。但是它们似乎实现了相同的功能,都是能够让你间接的引用其他的对象。那么什么时候使用指针,什么时候使用引用就是一个我们需要考虑的问题了。第一我们必须知道在任何情况下引用都不能指向一个空值。它必须指向某些对象。所以如果你想使用一个变量去指向某一个对象,但是这个变量在某些时候可能指向任何对象,你应该把它声明为指针。相原创 2013-05-07 11:15:04 · 689 阅读 · 0 评论 -
引用计数的一种实现
#include using namespace std; class U_Ptr{ private: friend class HasPtr; int *ip; size_t use; U_Ptr(int *p):ip(p), use(1) { } ~U_Ptr() { delete ip; } }转载 2013-05-27 20:43:16 · 503 阅读 · 0 评论