如果我们使用一个投资行为的程序库: #include "stdafx.h" #include <iostream> #include <memory> using namespace std; class Investment { public: }; class InvestmentFactory { public: virtual Investment* createInvestment() { Investment * inV = NULL; return…
条款 13 :以对象管理资源 例:      voidf()      {           Investment *pInv = createInvestment();           ...                  //这里存在诸多“不定因素”,可能造成delete pInv:得不到执行,这可能就存在潜在的内存泄露.          delete pInv;      }  解决方法:把资源放进对象内,我们便可依赖C++的“析构函数自动调用机制”确保资源被释放.     许…
三.资源管理       资源就是一旦你使用了它,将来不用的时候必须归还系统.C++中最常用的资源就是动态内存分配.其实,资源还有 文件描述符.互斥器.图形界面中的字形.画刷.数据库连接.socket等. 1.        以对象管理资源       void f() {     investment *plv = createInvestment();     //这里存在很多不定因素,可能造成下面语句无法执行,这就存在资源泄露的可能.     delete plv; }      这里我们…
条款08  别让异常逃离析构函数: 假设在析构函数其中发生了异常,程序可能会过早结束或者导致不明白行为(异常从析构函数传播出去) 看代码: #include <iostream> using namespace std; class DBConnection { public: void close() { int i = 3; int j = 0; int k = i/j; printf("%d\n",k); } }; class DBConn { public: DBC…
条款11: 在operator= 中处理"自我赋值" 在实现operator=时考虑自我赋值是必要的就像 x=y .我们不知道变量x与y代表的值是否为同一个值(把x和y说成是一个指针更恰当一点). 例如以下 第一版: #include <iostream> using namespace std; class bitmap { public: bitmap() { cout<<"调用bitmap()无參构造函数"<<endl; }…
第5条:避免创建不必要的对象 本条主要讲的是一些反面教材,希望大家引以为鉴. ①无意中使用自动装箱导致多创建对象. public class Sum { public static void main(String[] args) { Long sum = 0L; for (long i = 0; i < Integer.MAX_VALUE; i++) { sum += i; } System.out.println(sum); } } sum被声明为Long而不是long,意味着每次i都要被自…
第1条:考虑用静态工厂方法代替构造器 通常情况下,我们创建一个对象采取new的形式,但是还有一种方法也是经常使用到的,它的名称叫做静态工厂方法. 例如,java中基本类型boolean的包装类Boolean就采用了这种方式,源代码如下: public static Boolean valueOf(boolean b) { return (b ? TRUE : FALSE); } 当然,除了valueOf这种比较low的名字之外,我们常用的还有getInstance(最常见),newInstanc…
1.优先考虑用静态工厂方法代替构造器2.遇到多个构造器参数时要考虑使用构建器Builder解决参数过多,不可变类型.私有构造方法,静态类的构造方法提供必要参数,剩下可选.new xxx.build()3.用私有构造器或者枚举类型强化Singleton属性.单例:无状态.实现单例如果实现序列化接口,可能会在序列化和反序列化导致有多个实例产生.枚举的实现方法可以解决,但是枚举不太好去继承.枚举是目前最佳实现单例的方法.4.通过私有构造器强化不可实例化的能力5.优先考虑依赖注入来引用资源.资源都是单例…
第7条:避免使用终结方法 这一条讲的简直是不知所云.先简单记下来其中说出的几条: ①显式终止方法的典型例子有InputStream.OutputStream和java.sql.Connection上的close方法,以及java.util.Timer上的cancel方法.这些方法一般与try-catch连用,在finally中调用显式的终止方法.终结方法的意义在于这些close方法忘记调用时,充当安全网的作用(感觉扯淡,close都会忘,终结方法能记得?). ②finalize方法,源自Obje…
第3条:用私有构造器或者枚举类型强化Singleton属性 这一条,总体来说,就是讲了一个小技巧,将构造器声明为private,可以实现单例.具体有以下几种实现的方式. ①最传统的单例实现模式,可能有很多变种,核心思想是私有化构造器. public class Singleton { private static final Singleton INSTANCE = new Singleton(); private Singleton(){}; public static Singleton g…
Effective STL 读书笔记 标签(空格分隔): 未分类 慎重选择容器类型 标准STL序列容器: vector.string.deque和list(双向列表). 标准STL管理容器: set.multiset.map和multimap. 非标准STL序列容器: slist(单向列表)和rope(重型字符串?). 非标准STL关联容器: hash_set.hash_multiset.hash_map和hash_multimap.(c++11引入了unordered_set.unordere…
Effective STL 读书笔记 本篇文字用于总结在阅读<Effective STL>时的笔记心得,只记录书上描写的,但自己尚未熟练掌握的知识点,不记录通用.常识类的知识点. STL按照容器类型,可以分为标准序列容器(deque,vector,list,string),标准关联容器(map,multimap,set,multiset),另外,还有非标准容器,序列类型有slist和rope,关联类型有hash_**类相关容器.标准关联容器总是保持排列顺序. 在关联容器中,确保关联容器对于所使…
SQL Server2012 T-SQL基础教程--读书笔记(1-4章) SqlServer T-SQL 示例数据库:点我 Chapter 01 T-SQL 查询和编程背景 1.3 创建表和定义数据的完整性 1.3.1 创建表 1.3.2 定义数据的完整性 1. 主键约束 2. 唯一约束 3. 外键束约 4. CHECK约束 5. 默认约束 Chapter 02 单表查询 2.1 SELECT 语句元素 2.1.7 TOP和OFFSET-FETCH 1. TOP筛选 2. OFFSET-FETC…
第一部分 让自己习惯C++ 条款01:视C++为一个语言联邦 一.要点 ■ c++高效编程守则视状况而变化,取决于你使用c++的哪一部分. 二.扩展 将c++视为一个由相关语言组成的联邦而非单一语言会帮助你更好的理解,其由c.object-oriented c++.template c++和stl四部分组成. 条款02:尽量以const,enum,inline替换#defines 一.要点 ■ 对于单纯变量,最好以const对象或enums替换#defines. ■ 对于形似函数的宏,最好改用i…
条款一十三:以对象管理资源 1.把资源放进对象内,我们便可依赖C++的“析构函数自动调用机制“确保资源被释放. 2.auto_ptr是个”类指针对象“,也就是所谓”智能指针“,其析构函数自动对其所指对象调用delete. void f() { std::auto_ptr<Investment>pInv(createInvestment());//调用factory函数使用pInv经由auto_ptr的析构函数自动删除pInv ... } 获得资源后立即放进资源管理对象内.管理对象运用析构函数确…
这一节基本讲述的是将资源放进管理对象,防止忘记释放资源. 1.一般New和Delete使用场景 void fun() { SimpleClass* pSimpleClass1 = new SimpleClass; .... // 如果这中间发生异常返回,则delete pSimpleClass1将不会被执行,造成内存泄漏 delete pSimpleClass1; SimpleClass* pSimpleClass2 = createSimpleClass(); .... // 如果这中间发生异…
以对象管理资源 通过对象的析构函数的自动调用来自动释放资源 第一部分:几种典型的以对象管理资源的例子 1. STL::auto_ptr 获取资源后立刻放入资源管理对象 std::auto_ptr<Investment> pInv(createInvestment()); 当pInv生命周期结束时,自动释放资源 注意:auto_ptr有一个奇怪的性质:不会有多个auto_ptr同时指向同一个资源. std::auto_ptr<Investment> pInv2(pInv); // p…
auto_ptr是C++标准库提供的类模板,它可以帮助程序员自动管理用new表达式动态分配的单个对象.auto_ptr对象被初始化为指向由new表达式创建的对象,当auto_ptr对象的生命期结束时,动态分配的对象会被自动释放.auto_ptr为动态分配内存提供了大量的便利和安全性.通过使用auto_ptr,程序员不再需要关心new出来的对象何时delete,而且在子程序异常跳出时仍能保证动态分配的对象正常析构. 在使用auto_ptr之前,必须包含以下的头文件: #include<memory…
Effective C++在此条款中总结出两个结论 1.对于单纯常量,最好以const对象或enum替换#define 2.对于形似函数的宏,最好改用inline函数替换#define 接下来我们进行详细的探讨. const替换#define的讨论 例如: #define ASPECT_RATIO 1.653 原书给出的解释大意是: 你所使用的名称(ASPECT_RATIO)可能并未进入记号表(symbol table),原因也许是记号名称ASPECT_RATIO从未被编译器看见,也许在编译器开…
很早之前就听过这本书,找工作之前读一读.看了几页,个人感觉实在是生涩难懂,非常不符合中国人的思维方式.之前也有博主做过笔记,我来补充一些自己的理解. 我看有人记了笔记,还不错:http://www.360doc.com/content/12/0426/20/7899729_206769585.shtml 这位博主还写了more effective c++的读书笔记:http://bellgrade.blog.163.com/blog/static/83155959200863113228254/…
本文是王福强所著<<spring揭秘>>一书的读书笔记 我们前面就说过,Spring的IoC容器时一个IoC Service Provider,而且IoC Service Provider提供两个功能对象的创建,依赖关系的管理. 不过,IoC容器这个词中,我们还得关注容器二字.它还包含了一些别的功能,如下图 Spring提供了两种类型的容器,分别是BeanFactory与ApplicationContext. 它们的区别在于: BeanFactory:对于它所管理的bean,采取的…
接上篇JAVA编程思想读书笔记(三)--RTTI No1: 类的克隆 public class MyObject implements Cloneable { int i; public MyObject(int i) { this.i = i; } @Override protected Object clone() { Object o = null; try { o = super.clone(); } catch (CloneNotSupportedException e) { Syst…
Effective Java是一本经典的书, 很实用的Java进阶读物, 提供了各个方面的best practices. 最近终于做完了Effective Java的读书笔记, 发布出来与大家共享. Background 看了历史, 写第一篇笔记居然是2016年的事情了, 中间半途而废搁置了好长时间, 去年生病的时候捡起来看了一些, 今年终于看完了. 做这个笔记的目的主要是为了个人学习, 把一本书读薄, 也留下以后可以查阅翻阅的资料. 写博客这么多年, 我觉得有一个很大的好处是, 有时候会有一个…
本文是王福强所著<<spring揭秘>>一书的读书笔记 我们前面就说过,Spring的IoC容器时一个IoC Service Provider,并且IoC Service Provider提供两个功能对象的创建,依赖关系的管理. 只是,IoC容器这个词中,我们还得关注容器二字.它还包括了一些别的功能,例如以下图 Spring提供了两种类型的容器,各自是BeanFactory与ApplicationContext. 它们的差别在于: BeanFactory:对于它所管理的bean,採…
问题聚焦: 从这条准则开始,都是关于资源管理的. 资源,一旦用了它,将来必须还给系统. 本条准则,基于对象的资源管理办法,建立在C++的构造函数,析构函数和拷贝函数(拷贝构造函数和重载赋值操作符)的基础上. Demo: root class Investment: class Investment { ... }; // 工厂函数 Investment* createInvestment(); // 返回指向一个Investment或者其子类的对象,调用者有责任删除它 // 考虑如下调用 voi…
C++相比Java等含有gc的语言来说,内存管理方面(也包括资源管理)比较令人头疼.一些初级程序员,甚至是一些经验丰富的老程序员,也会经常在资源管理上犯错.这时候就需要一个能够自动管理资源的东西(gc),但是由于C++本身没有提供,那么只有我们自己实现了. 本节我不打算直接按照<Effective C++>本节的内容进行写作,而是手动实现一个智能指针(想想还有些小激动呢^_^). 首先,我们先编写一个测试代码(先写测试代码总是一个好习惯): //test.h #pragma once #inc…
永远在使用对象之前先将它初始化.对于无任何成员的内置类型,你必须手工完成此事. 至于内置类型以外的任何其他东西,初始化责任落在构造函数身上.规则很简单:确保每一个构造函数都将对象的每一个成员初始化. 构造函数成员初始化列表: 这里有一个规则:总是在初始化列表中列出所有成员变量,即使有的成员变量是内置类型(内置类型的初始化和赋值成本相同). 成员初始化顺序 base classes 早于 derived classes 被初始化,class 的成员变量总是以其声明次序被初始化 一个编译单元内定义的…
条款02: 尽量以 const, enum, inline 替换 #define 这个条款或许可以改为“宁可以编译器替换预处理器”. 编译过程: .c文件--预处理-->.i文件--编译-->.o文件--链接-->bin文件 如果你做出这样的事: #define ASPECT_PATIO 1.653 记号名称 ASPECT_PATIO 从未被编译器看见:也许在编译器开始处理源代码之前它就被预处理器移走了.于是记号名称 ASPECT_PATIO 有可能没有进入符号表(symbol tabl…
尽管Object是一个具体的类,但设计它主要是为了扩展.它的所有非final方法都有明确的通用约定.任何一个类在override时,必须遵守这些通用约定. 一.覆盖equals时请遵守通用的约定 1.Object中默认的equals方法约定是:类的每个实例都只与它自身相等.当类有自己特有的“逻辑相等”的概念时,就应该覆盖equals方法. 2.Timestamp对Date进行了扩展,Timestamp的equals实现确实违反了对称性.如果Timestamp和Date混合一起使用,可能导致不正确…
一.考虑用静态工厂方法代替构造器 这里的静态工厂方法是指类中使用public static 修饰的方法,和设计模式的工厂方法模式没有任何关系.相对于使用共有的构造器来创建对象,静态工厂方法有几大优势: 1.静态工厂方法有名称:通过有意义的静态工厂方法名称可以很好的表达工厂方法的作用,易于区别功能相似的多个静态工厂方法. 2.静态工厂方法可以有更复杂的生产对象逻辑,不仅仅是新建一个对象:既可以新建一个对象,也可以使用缓存的对象. 3.静态工厂方法可以返回原返回类型的任何子类型的对象:由于接口不能有…