设计模式
brahmsjiang
这个作者很懒,什么都没留下…
展开
-
代理、适配器和外观模式
重写基于另一组类的包装器接口是常有的事儿。创建包装器API的副作用是影响性能,函数调用开销+额外代码量,但为了创建更有针对性、质量更高的API是值得的。原创 2020-12-18 16:11:18 · 153 阅读 · 1 评论 -
简单工厂和扩展工厂模式
工厂模式一个创建型的设计模式。它允许创造对象时不用知晓所创建对象的具体类型。一般C++的构造函数有以下限制:1. 没有返回值2. 命名限制(构造函数名字必须和类名字相同)3. 不能声明虚构造函数4. 静态绑定创建(构造函数没有运行时动态绑定的概念,编译时须能够确定具体类型名)而工厂模式绕开了以上限制。它们经常和继承一起使用,即派生类能够重写方法并返回派生类的实例。常见做法是使用抽象基类。简单工厂抽象基类是包含纯虚函数的类,不能使用new实例化。其用于描述各个类共享的行为,指定了派生类必原创 2020-12-16 17:35:35 · 226 阅读 · 0 评论 -
单例线程安全实现、DCLP及其注意事项、饿汉懒汉实现方式
单例设计模式确保一个类仅存在一个实例,并提供了对此唯一实例的全局访问点。可以认为单例是一种更加优雅的全局变量。相对于全局变量,它还有其他优点:1. 确保一个类只创建一个实例2. 为对象分配和销毁提供控制3. 支持线程安全地访问对象的全局状态4. 避免污染全局名字空间用C++实现单例为了阻止客户自行分配、销毁、复制该类对象,将默认构造、析构、复制构造和赋值操作符都声明为私有并且不实现。class Singleton{public: static Singleton&原创 2020-12-14 22:58:28 · 247 阅读 · 0 评论 -
Effective C++ (E3 28)笔记之避免返回指向对象内部成分的handles、浅拷贝与深拷贝的探讨
篇幅较长,先按部就班地从类的实现开始讨论吧。比如一个类用于表示“点”:class point{public: point(int xx=0,int yy=0) :x(xx),y(yy) { cout<<"point cons"<<endl; } point(const point& pt) //可访问性是相对于类型来说的,而不是实例 :x(pt.x),y(pt.y)原创 2018-01-27 01:34:48 · 209 阅读 · 0 评论 -
Effective C++ (E3 25)笔记之写一个不抛异常的swap函数
STL的swap可以说是异常安全编程的脊柱,以及是用来处理自我复制可能性的一个常见机制。典型实现如下:namespace std{ template void swap(T& a, T& b) { T temp(a); a = b; b = temp; }}但其用到三个对象的复制,即a复制到temp,b赋值到a,temp赋值到b。对于某些handle类(使用pim原创 2018-02-03 12:38:03 · 179 阅读 · 0 评论 -
Effective C++ (E3 43)笔记之学会处理模板化基类内的名称
有个程序要传送信息到不同公司,信息可能是密码也可以能使未经处理的。传送的不同公司的代码不同,在编译期间我们有足够信息决定传送到哪一个公司,于是采用基于template的解法:class CompanyA{public: void sendClrText(const std::string& str) { cout"<<str.data()<<endl; } void send原创 2018-02-04 17:20:34 · 229 阅读 · 0 评论 -
Effective C++ (E3 10、11)笔记之在operator=中返回*this、处理自我赋值
为了实现“连锁赋值”,即 Widget wig4,wig3; wig3.printname(); wig4.printname(); //continous assigiment wig4=wig3=wig1; wig3.printname(); wig4.printname();operator=必须返回一个reference指向操作符的左侧实参。这项不成文的规定同样适用于其他赋值...原创 2018-03-10 00:33:59 · 294 阅读 · 0 评论 -
Effective C++ (E3 24)笔记之使用非成员函数重载多元运算符,以支持所有参数被隐式转换
建立数值类型时,令class支持隐式类型转换是合理的。如果想通过运算符重载来世类对象支持算术运算,那么该选择成员函数、非成员函数还有友元函数?假设此类描述有理数:class rational{public: rational(int num=0, int deno=1) :m_num(num),m_deno(deno){} int retnum() const{ ret原创 2018-01-26 00:09:32 · 406 阅读 · 0 评论 -
Effective C++ (E3 39)笔记之审慎使用private继承
private继承不是一种is-a关系,是一种"根据某物实现出"的实现技术而已.1.编译器不会将derived对象转为base对象(包括指针),当然base对象也不会被转为derived对象.见代码:class person{};class student:private person{ operator person(){ };};void eat(const原创 2018-01-17 16:24:49 · 151 阅读 · 0 评论 -
Effective C++ (E3 34、36)笔记之接口继承和实现继承
当类的成员函数为pure virtual、impure virtual、non-virtual时,派生类对这些函数进行继承其意义是不同的:pure virtual:只继承接口impure virtual:继承接口和一份缺省实现non-virtual:继承类继承其接口以及一份强制性实现,继承类绝不应该重新定义现在先从impure virtual讨论。有一个类描述飞原创 2018-01-13 01:56:27 · 249 阅读 · 0 评论 -
Effective C++ (E3 33)笔记之名称遮掩规则及其应对手法
C++中名称遮掩规则即为:遮掩名称。这个遮掩的名称和类型无关。编译器按照从最内部作用域向外逐个查找,直到找到匹配的名称为止。Base类:#includeusing namespace std;class Base{private: int x;public: virtual void mf1()=0; virtual void mf1(int){ cout<<"原创 2018-01-13 00:47:22 · 261 阅读 · 0 评论 -
Effective C++ (E3 20、21)笔记之以传const引用代替传值、谨慎指定返回类型
传递函数参数时,使用传值方式会对传入对象进行复制。如以下代码:#include using namespace std;class A{public: A(){ cout<<"A::A()"<<endl; } virtual ~A(){ cout<<"A::~A()"<<endl; } A(const A&){ cout<<"A::A(const A&)"<原创 2018-01-13 21:22:57 · 201 阅读 · 0 评论 -
Effective C++ (E3 35)笔记之替代virtual函数的若干方案
假设要设计个游戏,里面不同类人物有不同生命值的计算方法:那么基类定义一个impure virtual health函数,让派生类去同时继承它的接口和一份缺省实现,当然也可以重新定义。这是一个最常见而无甚新意的设计。现有几种替代设计方案。一、用NVI(non-virtual interface)手法实现template methodclass chara{public: vi原创 2018-01-13 23:38:19 · 223 阅读 · 0 评论 -
Effective C++ (E3 13)笔记之以对象管理资源
在Effective C++的“资源管理”一章中,讨论了如何以对象管理资源的方法。以我现在理解来看,是为了方便用户通过API管理资源,尤其是引导其正确地使用资源。当用户取得一个指向某对象/资源的指针时(一般在堆中构建),何时delete该对象取决于用户,甚至无法预测(如在析构前抛出异常)。从而造成内存泄漏等问题。解决上述问题的机制便是RAII,实现要点有:1.把指向资源的指针保原创 2017-12-29 12:27:10 · 162 阅读 · 0 评论 -
Effective C++ (E3 31)笔记之降低文件间编译依赖 & 前向声明
有个Preson类,h文件中声明、cpp文件中定义(实现):#include <string>#include <memory>#include <iostream>class Person{public: Person(const std::string& name); std::string name() const;pr...原创 2018-01-06 23:59:47 · 308 阅读 · 0 评论 -
Effective C++ (E3 22、23)笔记之成员变量声明为private、以非成员非友元函数替代成员函数
成员变量就应该是private。理由一:语法一致性。对客户而言每样东西都是函数。理由二:可通过成员函数严格控制其读写权限、添加约束条件。根本理由:封装性。声明为private则客户只能通过函数接口访问,客户不用关心实现方法,这为“所有可能实现”提供了弹性。并且以接口替代直接对变量的访问,从代码破坏量来说,前者将远远小于后者。客户很可能只需重新编译,甚至可以消除重新编译(条款31)。原创 2018-01-24 22:03:10 · 278 阅读 · 0 评论 -
Effective C++ (E3 5、6)笔记之禁止默认拷贝构造和赋值重载操作符
即使声明一个空类class A{}编译器会默认指定四个函数:default构造函数、析构函数、拷贝构造函数、赋值重载操作符class A{ A(){} ~A(){} A(const A&){...} //源对象的每一个non-static成员变量拷贝到目标对象 const A& operator=(const A& rhs){...}原创 2017-12-29 14:41:29 · 258 阅读 · 0 评论 -
Effective C++ (E3 7)笔记之为多态基类声明virtual析构函数
#include#includeusing namespace std;class A{public: A(){ cout<<"A: cons"<<endl; } virtual ~A(){ cout<<"A: des"<<endl; } virtual void print(){ cout<<"A原创 2017-12-29 15:13:41 · 271 阅读 · 0 评论