01 2012 档案
摘要:只要定义一个变量,而其类型带有一个构造函数或析构函数, 那么当程序的控制流到达这个变量定义时,变承受构造成本;当变量离开作用域时,便承受析构成本。 //这个函数过早定义变量“encrypted” std::string encryptPassword(const std::string& password) { using namespace std; ...
阅读全文
摘要:缺省情况下swap动作可由标准程序库提供的swap算法完成: namespace std{ template<typename T> void swap(T& a, T& b) { T temp(a); a = b; b = temp; } ...
阅读全文
摘要:令class支持类型隐式转换通常是个糟糕的主意。当然这条规定在建立数值类型时,有例外。假设一个class用来表现有理数,允许整数 “隐式转换为”有理数似乎很合理。 class Rational{ public: Rational(int numerator = 0, int denominator = 1); //刻意不为explicit;允许int-to-...
阅读全文
摘要:有个class来表示网页浏览器: class WebBrowser { public: void clearChache(); void clearHistory(); void removeCookies(); protected: private: }; 许多用户会想一整个执行所...
阅读全文
摘要:为什么不采用public成员变量 首先,语法一致性考虑,客户唯一能访问对象的方法就是通过成员函数,客户不必考虑是否该记住使用小括号()。 其次,使用函数可以让你对成员变量的处理有更精确的控制。如果成员变量是public,每个人都可以读写它,但是如果你也函数 取得或设定其值,你就可以实现“不准访问”、“只读访问”,以及”读写访问”甚至”唯写访问“: class AccessLeve...
阅读全文
摘要:考虑有理数的class: class Rational { public: Rational(int numerator = 0, int denominator = 1); protected: private: int n, d; friend Rational operator*(const ...
阅读全文
摘要:缺省情况下c++以by value 的方式传递对象(或来自)函数。函数参数是以实参的副本为初值,用函数获得的也是函数返回值的一个副本 这些副本由对象的copy构造函数产出,这可能使得pass-by-value成为昂贵的操作: class Person { public: Person(); virtual ~Person(); ...
阅读全文
摘要:设计优秀的classes和是一项艰巨的工作,因为设计好的types是一项艰巨的工作。设计出至少像c++内置类型一样好的classes。 几乎每一个class都要求面对以下提问,回答往往导致你的设计规范: 1,新type的对象应该如何创建和销毁? 包括构造和析构函数,内存分配和释放函数(operator new, operator delete,operator new[], o...
阅读全文
摘要:如果客户企图使用某个接口而却没有获得他所预期的行为,这个代码就不该通过编译,如果代码通过了编译, 它的作为就该是客户所想要的。 class Date { public: Date(int month, int day, int year); ... }; 第一,以错误的次序传递参数: Date(3...
阅读全文
摘要:假设一个函数用来揭示处理程序的优先权 int priority(); 另一个函数用来在动态分配的Widget上进行某些带有优先权的处理: void processWidget(std::tr1::shared_ptr<Widget> pw, int priority); 考虑调用processWidget: processWidget(new Widget, pri...
阅读全文
摘要:当你使用new,有两件事情发生。 第一,内存被分配出来(通过名为operator new的函数)。 第二,针对此内存会有一个(或多个)构造函数被调用。当你使用delete,也有两件事情发生:针对此内存会有一个或多个析构函数被调用,然后内存被释放。 数组所用的内存通常还包括”数组大小”的记录,以便delete知道调用多少次析构函数。 当你调用new时使用[],你必须在对应...
阅读全文
摘要:资源管理类避免直接处理资源,但是许多APIs直接涉及资源,所以应该提供返回原始资源的函数。 tr1::shared_ptr和auto_ptr都提供一个get成员函数,用来执行显式转换,返回智能指针内部的原始指针(的复件)。 std::tr1::shared_ptr<Investment> pInv(createInvestment()); int daysHeld(const ...
阅读全文
摘要:并非所有的资源都是heap-based,对那种资源来讲,auto_ptr和shared_ptr这样的智能指针往往不适合作为资源掌管着。你可能需要 自己建立自己的资源管理类。 例如,处理类型为Mutex的互斥器对象,有lock和unlock两函数可用。 void lock(Mutex* pm); void unlock(Mutex* pm); class Loc...
阅读全文
摘要:资源是,一旦用了,将来必须还给系统,除了内存常见的还有文件描述符(file description)、互斥锁、图形界面中的笔刷、数据库连接 以及网络socket。考虑到异常、函数内多重回传路径、程序维护员软件改动却没有理解随之而来的冲击,发现资源管理的特殊手段还不很充分够用。 假设一个各式各样的投资类型继承的一个root class Investment: class Inve...
阅读全文
摘要:copy构造函数和copy assignment操作符,我们称他们为copying函数。这些“编译器生成版”的行为:将被烤对象的所有成员变量 都做一份拷贝。 声明自己的copying函数, void logCall(const std::string funcName); class Customer { public: Custo...
阅读全文
摘要:假设建立一个class来保存一个指针指向一块儿动态分配的位图(bitmap) class Bitmap{...}; class Widget { public: protected: private: Bitmap* pb; }; 这个operator=实现代码表面看上来合理, 但自我赋值出现时并不安全,也不...
阅读全文
摘要:赋值的连锁式 x=y=z=3;被解析成x=(y=(z=3));为了实现“连锁赋值”,赋值操作符必须返回一个reference指向操作符的左侧实参, 这是你为class实现赋值操作符时应该遵循的协议: class Widget { public: Widget& operator=(const Widget& rhs) //返回类型是referenc...
阅读全文
摘要:每当创建一个交易对象,在审计日志中也要创建一笔适当记录。下面是一个看起来比较合理的做法: class Transaction { public: Transaction() { init(); } virtual void logTransaction() const { std::cout << "tran...
阅读全文
摘要:c++并不禁止析构函数抛出异常,但它不鼓励这样做: class Widget{ public: … ~Widget(); //假设可能抛出异常 }; void doSomething() { std::vector<Widget> v; … } 当vector v被销毁,它有责任销毁其内含的所有W...
阅读全文
摘要:c++明确指出,当derived class对象由一个base class指针删除,而该base class带着一个non-virtual析构函数,其结果未有定义— 实际执行时,通常发生的是对象的derived成分没被销毁。会造成“局部销毁”对象。 而避免这个问题很简单:给base class一个virtual析构函数。 任何class只要带有virtual函数,都几乎确定应该有一个v...
阅读全文
摘要:为了驳回编译器自动提供的功能, 可将相应的成员函数声明为private并不予实现。如果在成员函数或friend函数调用这些, 连接时会报错。将连接错误移至编译期是可能的,设置一个专门为了防止copying动作的base classs:class Uncopyable{protected: //允许derived对象构造和析构 Uncopyable(){} ~Uncopyable(){}private: //阻止copying Uncopyble(const Uncopyable&); Uncopyable& operator=(const Uncopyable&);};
阅读全文
摘要:编译给会为一个空类声明一个default构造函数、一个copy构造函数、一个copy assignment操作符、和一个析构函数。所有这些都是public且inline: class Empty{}; 就像是写了这样的代码: class Empty{ Empty(){…} Empty(const Empty& rhs) {…} ~E...
阅读全文
摘要:对象的成员变量的初始化动作发生在进入构造函数本体之前。ABEntry::ABEntry(const std::string& name, const std::list<PhoneNumber>& phones){ theName = name; //这些都是赋值,不是初始化 thePhones = phones; numTimesConsulted = 0;}这个构造函数首先调用default构造函数为theName, thePhones设初值,然后立刻对他们赋予新值ABEntry::ABEntry(const std::string& name, con
阅读全文
摘要:const 修饰指针:如果关键字const出现在星号*左边,表示被指物是常量,如果const出现在*右边表示指针自身是常量, 如果出现在两边表示被指物和指针都是常量; const std::vector<int>::iterator iter = vec.begin(); //iter的作用就像是T* const; ++iter;错误 std::vector<int>::const_iterator cIter = vec.begin(); //cIter的作用像个const T*; *cIter = 10;错误 const 修饰函数返回值:将operator*的返回值
阅读全文
摘要:Ubuntu 11.04已经发布了,想必很多同志已经迫不及待的尝鲜了~对于有2台电脑的同志,一台win7,一台Ubuntu可能是比较实际,比较符合国情的搭配。 于是乎,怎样高效的同时使用两台电脑就成为问题了。有的朋友可能倾向于用Ubuntu做主操作系统,然后远程桌面连上Win7使用,但是对于要使用VS编 程的朋友(比如我),最好的方法就是使用Win7做主系统,然后远程桌面连上Ubuntu~好了,废话不多说,昨晚装好Ubuntu之后,在网上搜了一圈远程桌面的方法,不敢独享,在此小小整理一下,不是本人原创……具体方法:Ubuntu下的操作1、首先你要有Ubuntu11.04,其实10.04也可以使
阅读全文

浙公网安备 33010602011771号