自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(34)
  • 资源 (1)
  • 收藏
  • 关注

翻译 Item 51 new和delete的规则

<br />● 全局new/delete重载<br />void * operator new(std::size_t size) throw(std::bad_alloc){ using namespace std; if (size == 0) { // C++规定:零申请也要给一个字节 size = 1; } void* mem = NULL; while (true) { mem = malloc(size); if (mem) { ret

2011-05-31 14:01:00 592

翻译 Item 52 new/delete成对儿出现

<br />● 通用概念<br />Widget *pw = new Widget;<br />其实分为两步:<br />1> 调用operator new分配内存<br />2> 调用ctor初始化对象<br /><br />如果第2步抛出异常,系统会自动调用<br />1> void operator delete(void *mem) throw();<br />2> void Widget::operator delete(void *mem, std::size_t s

2011-05-31 13:26:00 610

翻译 Item 50 重载new和delete

<br />重载new和delete的目的:<br />● 监视内存的使用。<br />1> new和delete没有一对一。new多了内存泄漏;delete多了导致未定义行为。此时需要一个带log的new。<br />2> overrun and underrun。向内存写数据时,写到了缓冲区的外面。此时需要new能申请稍大一点的空间存储标志位。<br />● 提高内存分配的效率<br />● 统计内存使用的规律<br /><br />下面是一个检测overrun/underrun

2011-05-29 18:11:00 597

翻译 Item 29 异常安全

<br />● 所谓“异常安全”,指的是当抛出异常时,要做到:<br />1> 资源无泄漏。申请的资源都释放掉。<br />2> 数据无破坏。数据都处于合法状态,不会出现无法解释的数据。<br /><br />满足这两点,就做到了基本的“异常安全”。<br />如果能在异常发生时把程序返回到调用前的状态,那就做到了高级的“异常安全”。<br />如果能保证绝不抛出异常,那就是完美的“异常安全”。<br /><br />● 如果某函数的异常列表是空的,表明它一旦出现异常,将是极严重的错

2011-05-28 18:45:00 721

转载 set_unexpected

<br />● 函数的声明<br />unexpected_handler set_unexpected (unexpected_handler f) throw();<br />设置新的,返回旧的<br /><br />● 说明<br />所谓的unexpected_handler,指的是函数。<br />如果某个函数出现异常,而该异常未被列到异常列表,则unexpected_handler被系统自动调用。<br /><br />该函数可以调用 terminate 或者 cstdl

2011-05-28 18:07:00 5390 2

翻译 Item 33 派生时小心重名函数族

<br />1> 普通变量的名字覆盖<br />int x;void someFunc(){ double x; // 虽然是double,但对编译器而言,还是和 std::cin >> x; // 上面的int重名,此处只能访问double的} <br /> <br />2> 派生时发生的名字覆盖<br />class Base {private: int x;public: virtual void mf1() = 0; virtual void m

2011-05-28 17:07:00 610

翻译 Item 37 子类不能修改成员函数的默认参数值

<br />class Shape {public: enum ShapeColor { Red, Green, Blue }; virtual void draw(ShapeColor color = Red) const = 0; // 默认是红 ...};class Rectangle: public Shape {public: virtual void draw(ShapeColor color = Green) const; // 默认改为绿 ...}

2011-05-28 16:04:00 772

翻译 Item 35 考虑虚函数的替代者

<br />● NVI: Non-Virtual Interface<br />class GameCharacter {public: int healthValue() const // 1. 子类不能重定义 { ... // 2. preprocess int retVal = doHealthValue(); // 2. 真正的工作放到虚函数中 ...

2011-05-28 16:03:00 620

翻译 Item 23 多考虑“非成员、非友元”函数

<br />class WebBrowser {public: ... void clearCache(); void clearHistory(); void removeCookies(); ...};<br /> <br />为了提供一站式服务,定义一个“清除一切”的函数。下面是两种方案:<br /><br />1> 成员函数<br />class WebBrowser {public: ... void clearEverything(); ...

2011-05-28 16:01:00 722

翻译 Item 20 传引用的好处

<br />1> 不仅效率高,而且避免了“对象切割”的问题:<br />class Window {public: ... std::string name() const; virtual void display() const; };class WindowWithScrollBars: public Window {public: ... virtual void display() const;};void printNameAndDisp

2011-05-28 15:58:00 720

翻译 Item 19 类的设计

设计一个类,要考虑如下几方面:1> 如何创建、销毁?这会影响:ctor, dtor, operator new, operator delete2> 初始化和赋值有什么差别?3> 传值的时候要做什么?会影响copy ctor4> 合法值都有哪些?会影响ctor、赋值、setter、异常。5> 是否继承自某个类体系?如果是,要遵循其定义规范。6> 需要什么样的类型转换?是隐式的还是显示的?7> 操作符8> 编译器生成的函数是否有不需要的9> 谁可以访问其成员10> 如果

2011-05-28 15:57:00 638

翻译 Item 18 不易误用的接口

● 用类型限制用户class Date {public: Date(int month, int day, int year); ...};Date d(30, 3, 1995); // 日、月用反了Date d(2, 30, 1995); // 日、月不匹配重新设计接口:struct Day { explicit Day(int d) :val(d) {} int val;};struct Month { explicit Month(int m) :v

2011-05-28 15:56:00 610

翻译 Item 5 编译器自动生成和调用的函数

● 一个空类,编译器会在其中加入四个public的内联函数:1> default ctor2> copy ctor 和一个赋值函数:负责处理non-static成员变量3> 一个非虚拟的dtor;如果该类派生自一个有虚拟dtor的基类,结论相反这四个函数会在被调用的时候构造出来。● 下面三种情况,编译器不会自动生成赋值函数,会报错。templateclass NamedObject {public: NamedObject(const char *name, const T&

2011-05-28 15:54:00 707

翻译 内存使用的N个建议

1> 使用alloc、new、copy族(如mutableCopy)创建的对象,要使用release/autorelease。使用retain的对象,同样处理。没有使用这四者的,不能用release/autorelease。// 必须releaseTestClass *ptr = [[TestClass alloc] init];...[ptr release];// 不用releaseNSString *str;str = [NSString stringWithFormat:

2011-05-24 09:37:00 1128

翻译 Item 11 赋值函数的自赋值

class Widget { ... };Widget w;...w = w; // 1. 能通过编译,但是明显不合理!...a[i] = a[j]; // 2. ij可能相同*px = *py; // 3. 二者可能相同或有继承关系上面的三种情况,都是给自己赋值,要在赋值时检查。class Bitmap { ... };class Widget { ...private: Bitmap *pb;};// 既无赋值安全性,又无异常安全性的

2011-05-20 12:48:00 712

翻译 Item 12 注意copy ctor和赋值函数

如果一个类有自定义的copy ctor和赋值函数,那么:● 在向其添加成员变量的时候,也要向其所有的ctor和赋值函数添加变量的初始化● 派生的时候,也要调用基类相关的函数:class PriorityCustomer: public Customer {public: ... PriorityCustomer(const PriorityCustomer& rhs); PriorityCustomer& operator=(const PriorityCustomer& rhs);

2011-05-17 12:04:00 692

翻译 Item 49 new_handler

内存分配失败时,老的C++编译器返回null空指针;新的则抛出bad_alloc异常。在此之前,operator new要先调用一个函数。此函数可由用户定制,叫做new_handler。由该函数处理内存不足这个问题。直到找到合适的内存为止,将反复调用该函数。该函数由std::set_new_handler注册给operator new:namespace std { typedef void (*new_handler)(); new_handler set_new_handler(ne

2011-05-17 10:30:00 527

翻译 Item 48 TMP编程介绍

Item 47介绍了一个advance的例子。如果用typeid的方式,会出现两个问题。其中之一如下:templatevoid advance(IterT& iter, DistT d){ if (typeid(typename std::iterator_traits::iterator_category) == typeid(std::random_access_iterator_tag)) { iter += d; // compile error } ...

2011-05-16 15:46:00 879

翻译 Item 47 用trait类提供类型信息

STL主要由容器、迭代器和算法这三类模板组成。也包含一些工具模板,比如:templatevoid advance(IterT& it, DistT d); // it += d在实现上,只有支持随机访问的迭代器才能用+=,功能稍弱的只能用++和--重复执行。迭代器分5类:1> Input Iterator  只能前行,一次一步,指谁读谁,而且只能读一次。代表:istream_iterator2> Output Iterator 与上同。用于写操作。代表:ostrea

2011-05-16 14:36:00 678

翻译 Item 46 模板需要类型转换的时候

把Item 24的例子改成模板:templateclass Rational {public: Rational(const T& numerator = 0, const T& denominator = 1); const T numerator() const; const T denominator() const; ...};templateconst Rational operator*(const Rational& lhs,

2011-05-14 17:11:00 584

翻译 Item 45 成员函数模板

<br />STL容器使用的iterator几乎都是智能指针,所以才能以++操作在节点之间移动。<br />但真正的指针,支持隐式类型转换:<br />1> 指向“派生类对象”的指针可以转成指向“基类对象”的指针;<br />2> 指向“non-const对象”的指针可以转成指向“const对象”的指针;<br /><br />智能指针做不到这些。<br /> <br />template<typename T>class SmartPtr {public: explicit S

2011-05-13 10:51:00 475

翻译 Item 44 与模板参数无关的代码

模板可以节省时间,减少代码的重复。假设有20个类,每个类15个成员函数。那么可以用一个类模板来定义,然后由编译器去实例化所需要的类。模板类的成员函数只在用到的时候才实例化。过度使用模板会导致目标代码的膨胀。要通过共性/异性分析防止这种事情发生。// n*n矩阵,元素类型为Ttemplateclass SquareMatrix {public: ... void invert(); // 求逆矩阵};SquareMatrix sm1;sm1.invert();

2011-05-12 11:01:00 610

转载 使用AIDL写Service

1> 首先定义服务器和客户端都要用到的接口:+--+--+ IBankService.aidl +--+--+package com.jxdsoft;interface IBankService { int getAccountBalance(); void setAccountOwner(in String name); void setAccountInfo(int deposit, in String pin); void showBankStatus();}2> 然后修改

2011-05-09 22:38:00 1072

翻译 Item 42 typename的使用

template class Widget;template class Widget;这两种声明区别不大。但在一些场合,必须使用typename。template // typename/class都行void f(const C& container, // 直接用C就好 typename C::iterator iter); // 必须加typename在C前面iterator是定义在C内部的类型。这样的类

2011-05-09 14:51:00 1514

翻译 checked delete

<br />+--+--+ File: deleter.h +--+--+<br /> <br />// 对Object只声明,不定义,编译器不会报错class Object;void delete_object(Object* p);<br /> <br />+--+--+ File: deleter.cpp +--+--+<br /> <br />#include "deleter.h"// 不知道Object的dtor也可以delete,编译器顶多会警告,不会报错。因为C++标准允许v

2011-05-09 11:49:00 590

翻译 Item 41 隐式接口和编译时多态

OOP编程与类属编程(generic programming)的一大区别:1> OOP使用显式的接口和运行时多态2> 类属编程使用隐式接口和编译时多态void doProcessing(Widget& w){ if (w.size() > 10 && w != someNastyWidget) { Widget temp(w); temp.normalize(); temp.swap(w); }}当你看到上面的代码时,你能在某个文件里找到下面的声明:class Wi

2011-05-09 10:49:00 597

翻译 Copy-and-swap

<br />为了在自定义类里重载一个异常安全(exception safe)的赋值操作符,创造了一个这样的习惯用语。也叫:Create-Temporary-and-Swap。<br />要想写健壮的C++代码,异常安全非常重要。<br />可以给异常安全分三级:<br />1> 基本安全:实现简单、代价小。应该作为常规手段。<br />2> 很安全:在任何场合都实现这一步不太可能。本例的赋值操作符重载算是一个。<br />3> 不抛出异常:可以看non-throwing swap。<br

2011-05-09 09:54:00 2166

翻译 Item 26 推迟变量的定义

对于有ctor和dtor的变量,如果定义得过早,就有可能带来不必要的构造和析构,从而带来性能上的损失。std::string encryptPassword(const std::string& password){ using namespace std; string encrypted; if (password.length() 如果中途出现异常而退出,则encrypted没有使用到,白白调用了ctor和dtor。

2011-05-09 00:01:00 911

翻译 Item 25 不应抛出异常的swap

通用的swap可以在stl里找到:namespace std { template // 1. std::swap的实现 void swap(T& a, T& b) { T temp(a); a = b; // 2. 只要T支持拷贝 b = temp; }}有很多类使用pimpl来分离实现与接口,对它们的swap要慎重。class WidgetImpl { // 真正的数据与函数实现放在这个类

2011-05-08 19:00:00 644

翻译 Item 36 非虚拟的成员函数不能重定义

class B {public: void mf(); ...};class D: public B { ... void mf(); // 1. 重定义基类中的non-virtual成员函数};D x;B *pB = &x;D *pD = &x;pB->mf(); // 调用的都是x的mf函数,若结果不一样,你是否pD->mf(); // 会奇怪?其实没什么,这类函数都是静态绑定虚函数才是动态绑定,在运行时根据指针指向的对象的实际类型,决定调用的函

2011-05-08 13:23:00 913

翻译 Item 6 如何禁用编译器产生的函数

如果要禁用编译器自动产生的copy ctor和拷贝构造函数,一般用下面的方法:class UniqueMoo {public: ...private: UniqueMoo(const UniqueMoo&); // 1. 只声明不定义,而且声明为私有,即可 UniqueMoo& operator = (const UniqueMoo&); // 1. 防止客户调用。用则产生编译错。若用};

2011-05-08 12:25:00 392

原创 Builder

<br />如果要构造一个组成部件很多的对象,即所谓的aggregate,可能要使用Director - Builder模式。<br />Director也叫Reader或Parser,负责解析输入,然后调用Builder相应的函数来构造对象相应的部件。<br />Builder模式的特征是,在构造对象时,一步步逐渐完成,而不是用一个函数一下子实现。<br />把整个构造过程抽象出N步,是为了让每一个步骤有多种实现方式。这样,最后构造出来的对象就会有多种表现形式。<br />所以,Build

2011-05-06 14:41:00 465

原创 Chain of Resposibility

<br />// ★ demo 1#include <iostream>#include <vector>#include <ctime>using namespace std;class Base { Base* next; // 1. 基类中要有"next"指针public: Base() { next = 0; } void setNext( Base* n ) { next = n; } void add( Base* n )

2011-05-05 12:16:00 551

翻译 observer

● 意图1> 在N个对象之间,建立一对多的联系:一个对象(主体)状态改变,其它对象(客体)都得到通知,并且做出相应的更新。2> 核心、通用的模块,封装到主体类;因个体而异的可变的功能,封装到客体类。3> 实现MVC体系中的View。● 问题一个软件设计在规模逐渐庞大时,其“图形化系统”/“监视系统”做不到相应的、很好的更新。● 实现步骤1> 找到应用程序中相似的、可选的、并行的、外围的功能/模块。2> 给它们定义一个通用接口(最好是个抽象类),这样它们就具备了互换性,多态了,

2011-05-02 17:15:00 564

Android ADT 10.0.0

The latest Eclipse plug-in for Android development.

2011-03-12

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除