C++ 模式设计
只写了MinGw/Linux API部分。所有相关的代码都是参考C++ API
C++ 11智能指针参考http://blog.csdn.net/zy19940906/article/details/50470087
<1>Pimpl
pointer to the implementation
计算一个累构造消耗的时间。
AutoTimer.h
//
// Created by Administrator on 2017/3/26.
// #ifndef MODERN_DESIGN_AUTOTIMER_H
#define MODERN_DESIGN_AUTOTIMER_H
#include <iostream>
#include <string>
#include <memory>
class AutoTimer
{
public:
explicit AutoTimer(const std::string &name);
~AutoTimer();
private:
class Impl;
Impl *_mimpl;
// std::unique_ptr <Impl> _mimpl; //智能指针,生命周期与类成员周期相同
}; #endif //MODERN_DESIGN_AUTOTIMER_H
AutoTimer.cpp
#include "AutoTimer.h"
#include <sys/time.h>
class AutoTimer::Impl
{
public:
double getElapsed() const
{
timeval end_time;
gettimeofday(&end_time,NULL);
double t1 = _start_time.tv_usec / 1e6 + _start_time.tv_sec;
double t2 = end_time.tv_usec / 1e6 + end_time.tv_sec;
return t2 - t1;
}
std::string _name;
timeval _start_time;
};
AutoTimer::AutoTimer(const std::string &name):_mimpl(new AutoTimer::Impl())
{
_mimpl->_name = name;
gettimeofday(&_mimpl->_start_time,NULL);
}
AutoTimer::~AutoTimer()
{
std::cout << _mimpl->_name << ":took " << _mimpl->getElapsed() << " secs" <<std::endl;
delete _mimpl; // 如果是智能指针不需用
_mimpl= NULL; // 如果是智能指针不需用
}
main.cpp:
AutoTimer timer("Houdini");
AutoTimer timer2("Maya");
输出:
Maya:took 0.000999928 secs
Houdini:took 0.000999928 secs
C语言的不透明指针。。。。实现就是这么轻松随意。。。。
AutoTimer.h
#ifndef MODER_DESIGN_C_AUTOTIMER_H
#define MODER_DESIGN_C_AUTOTIMER_H
// 声明一个指向AutoTimer结构体不透明的指针
typedef struct AutoTimer *AutoTimerPtr;
AutoTimerPtr AutoTimerCreate(const char *name);
void AutoTimerDestroy(AutoTimerPtr ptr); #endif //MODER_DESIGN_C_AUTOTIMER_H
AutoTimer.cc
#include "AutoTimer.h"
#include <sys/time.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h> struct AutoTimer
{
char *mName;
timeval mStartTime;
}; AutoTimerPtr AutoTimerCreate(const char *name)
{
AutoTimerPtr ptr = static_cast<AutoTimerPtr> (malloc(sizeof(AutoTimer))); // 因为我们用的是C++编译器,所以还是显式转换
if(ptr)
{
ptr->mName = strdup(name);
gettimeofday(&ptr->mStartTime,NULL);
}
return ptr;
}
static double GetElapsed(AutoTimerPtr ptr)
{
timeval end_time;
gettimeofday(&end_time,NULL);
double t1 = ptr->mStartTime.tv_usec / 1e6 + ptr->mStartTime.tv_sec;
double t2 = end_time.tv_usec / 1e6 + end_time.tv_sec;
return t2-t1;
}
void AutoTimerDestroy(AutoTimerPtr ptr)
{
if(ptr)
{
printf("%s took %f secs\n",ptr->mName,GetElapsed(ptr));
free(ptr);
}
}
main.cpp
AutoTimerPtr ptr = AutoTimerCreate("Houdini");
AutoTimerDestroy(ptr); AutoTimerPtr ptr2 = AutoTimerCreate("Maya");
AutoTimerDestroy(ptr2);
输出:
Houdini took 0.000000 secs
Maya took 0.000000 secs
Hello, World!
<2> 单例模式:
#include <iostream>
#include <thread>
#include <mutex>
using namespace std; class Singleton
{
public: static Singleton &GetInstance()
{
static Singleton *instance = NULL;
if(! instance)
{
std::mutex mutex;
if(! instance)
{
instance = new Singleton();
}
mutex.unlock();
}
return *instance;
}
static Singleton *GetInstancev2()
{
static Singleton m_instance;
return &m_instance;
} private:
Singleton()
{ }
~Singleton()
{ }
Singleton(const Singleton &);
const Singleton &operator=(const Singleton &); }; void threadFunc(string name,int uniqueId)
{
std::cout << "Singleton meomery:" << name << " -> " << uniqueId << " :Object &"<<&Singleton::GetInstance() <<"\n";
}
void threadRun()
{
thread thread_01(threadFunc,"houdini",);
thread thread_02(threadFunc,"maya",);
thread thread_03(threadFunc,"blender",); thread_01.join();
thread_02.join();
thread_03.join(); } int main()
{
Singleton &obj = Singleton::GetInstance();
std::cout << &obj <<std::endl;
//
std::cout << "test in thread \n";
threadRun(); // test use another
std::cout << "GetInstancev2 method create \n";
Singleton *obj2 = Singleton::GetInstancev2();
std::cout << obj2 <<std::endl; Singleton *obj3 = Singleton::GetInstancev2();
std::cout << obj3 << std::endl;
return ;
}
输出:
0x3e67c0
test in thread
Singleton meomery:Singleton meomery:blender -> Singleton meomery:maya -> houdini -> 0 :Object &0x3e67c0
1 :Object &0x3e67c0
2 :Object &0x3e67c0
GetInstancev2 method create
0x4060b0
0x4060b0
<3> 工厂模式
<4> 写时复制,节省内存最好的方法就是确实需要时再分配。所有客户共享一份唯一的资源,直到其中一个想修改这份资源为止,只有在哪个时间点才回构造副本.
template <class T> class CowPtr
{
public:
using RefPtr = std::shared_ptr<T> ;
inline CowPtr():mPtr(){}
inline CowPtr(const CowPtr<T> &other):mPtr(other.mPtr)
{
std::cout << "copy function "<< __LINE__<< "\n";
}
inline explicit CowPtr(T *other):mPtr(other){}
inline T &operator*()
{
std::cout<< "inline T &operator*()" <<__LINE__<<std::endl;
Detach();
return *(mPtr.get());
}
inline const T &operator*() const {
std::cout<< "inline const T &operator*() const" <<__LINE__<<std::endl;
return *(mPtr.get());
}
inline T*operator->()
{
std::cout<< "inline T*operator->()" <<__LINE__<<std::endl;
Detach();
return mPtr.get();
}
inline const T*operator->() const {
std::cout<< "inline const T*operator->() " << __LINE__<<std::endl;
return mPtr.get();
} inline const T*data()const
{
std::cout<< "inline const T*data()const " << __LINE__<<std::endl;
return mPtr.get();
} inline bool operator==(const CowPtr<T> &other) const {
return mPtr.get() == other.mPtr.get();
} inline bool operator!() const
{
return !mPtr.get();
}
inline CowPtr &operator=(T *other)
{
mPtr = RefPtr(other);
return *this;
} private:
inline void Detach()
{
T *temp = mPtr.get();
if(temp && !mPtr.unique())
{
mPtr = RefPtr(new T(*temp)); //
}
}
RefPtr mPtr; }; class WriteOnCopy
{
public:
WriteOnCopy(){}
std::string getValue() const
{
return *mData; }
void setValue(const std::string &value)
{
mData = new std::string(value);
} private:
CowPtr<std::string> mData;
}; int main()
{
CowPtr<std::string> string1(new std::string("houdini"));
CowPtr<std::string> string2(string1); //copy function
CowPtr<std::string> string3(string1); //copy function
string3->append("!!");
std::cout << *string3.data()<<std::endl; //houdini!!
std::cout << *string1<<std::endl; // houdini std::cout << "\n after change 1 \n";
CowPtr<std::string> pr_string1(new std::string("share me"));
char &char_ref = pr_string1->operator[](); //use the string operator[] function
CowPtr<std::string> pr_string2(pr_string1);
char_ref = 'H'; // after change 'H'
std::cout << *(pr_string1.data())<<std::endl; //sHare me
std::cout << *(pr_string2.data())<<std::endl; //sHare me // use write on copy
std::cout << "\nwrite on copy\n";
WriteOnCopy obj1;
obj1.setValue("hello");
WriteOnCopy obj2 = obj1;
std::string val = obj2.getValue();
WriteOnCopy obj3 = obj1;
obj3.setValue("There");
std::cout << "obj1 get data " << obj1.getValue() <<std::endl;
std::cout << "obj2 get data " << obj2.getValue() <<std::endl;
std::cout << "obj3 get data " << obj3.getValue() <<std::endl; return ;
}
<5>CPP Style
(1)更好的重载operator
GLY_Currency.h
#ifndef CPPSTYLE_GLY_CURRENCY_H
#define CPPSTYLE_GLY_CURRENCY_H #include <memory>
#include <iostream>
class GLY_Currency
{
public:
explicit GLY_Currency(int value);
~GLY_Currency();
GLY_Currency(const GLY_Currency&obj);
int getValue()const; // these operators must be declared as member functions
GLY_Currency &operator = (const GLY_Currency &rhs);
GLY_Currency &operator += (const GLY_Currency &rhs);
GLY_Currency &operator -= (const GLY_Currency &rhs);
GLY_Currency &operator *= (const GLY_Currency &rhs);
GLY_Currency &operator /= (const GLY_Currency &rhs); private:
class Impl;
std::unique_ptr <Impl> mImpl;
}; // these operators can (and should) be declared as free functions
inline GLY_Currency operator+(const GLY_Currency &lhs,const GLY_Currency &rhs)
{
// 复制一份是因为lhs+=rhs 会导致 lhs更改数据,因为lhs是const,所以不用复制构造,会导致
// 编译错误
return GLY_Currency(lhs)+=rhs;
}
inline GLY_Currency operator-(const GLY_Currency &lhs ,const GLY_Currency &rhs)
{
return GLY_Currency(lhs)-=rhs;
}
inline GLY_Currency operator*(const GLY_Currency &lhs ,const GLY_Currency &rhs)
{
return GLY_Currency(lhs)*=rhs;
}
GLY_Currency operator /(const GLY_Currency &lhs, const GLY_Currency &rhs)
{
return GLY_Currency(lhs) /= rhs;
} inline bool operator==(const GLY_Currency &lhs,const GLY_Currency &rhs)
{
return lhs.getValue()==rhs.getValue();
} inline bool operator!=(const GLY_Currency &lhs,const GLY_Currency &rhs)
{
return !(lhs==rhs);
}
inline bool operator<(const GLY_Currency &lhs,const GLY_Currency &rhs)
{
return rhs.getValue()<rhs.getValue();
}
inline bool operator>(const GLY_Currency &lhs,const GLY_Currency &rhs)
{
return rhs < lhs;
} inline bool operator<=(const GLY_Currency &lhs,const GLY_Currency &rhs)
{
return !(rhs > rhs);
}
inline bool operator>=(const GLY_Currency &lhs,const GLY_Currency &rhs)
{
return rhs <= lhs;
} inline std::ostream &operator <<(std::ostream &os,const GLY_Currency &rhs)
{
os << rhs.getValue();
return os;
} #endif //CPPSTYLE_GLY_CURRENCY_H
GLY_Currency.cpp
//
// Created by Administrator on 2017/5/2.
// #include "GLY_Currency.h"
class GLY_Currency::Impl
{
public:
int mValue;
}; GLY_Currency::GLY_Currency(int value):mImpl(new Impl)
{
mImpl->mValue = value;
}
GLY_Currency::~GLY_Currency() { } GLY_Currency::GLY_Currency(const GLY_Currency &obj):mImpl(new Impl)
{
mImpl->mValue = obj.mImpl->mValue;
}
int GLY_Currency::getValue() const {
return mImpl->mValue;
} GLY_Currency& GLY_Currency::operator=(const GLY_Currency &rhs) {
if (this != &rhs)
{
mImpl->mValue = rhs.mImpl->mValue;
}
return *this;
}
GLY_Currency& GLY_Currency::operator-=(const GLY_Currency &rhs) {
mImpl->mValue -= rhs.mImpl->mValue;
return *this;
}
GLY_Currency& GLY_Currency::operator+=(const GLY_Currency &rhs) {
mImpl->mValue += rhs.mImpl->mValue;
return *this;
} GLY_Currency& GLY_Currency::operator*=(const GLY_Currency &rhs) {
mImpl->mValue *= rhs.mImpl->mValue;
return *this;
}
GLY_Currency& GLY_Currency::operator/=(const GLY_Currency &rhs) {
mImpl->mValue /= rhs.mImpl->mValue;
return *this;
}
<6>Exception Basic
#include <iostream> /*
// BASIC
template <typename T>
T safe_divide(T const&a,T const &b)
{
if (b == 0)
{
const char *error = "b is zero do not allowed ";
throw error;
}
return a/b;
} int main()
{
double result = 0.0 ;
try
{
result = safe_divide(2.0,0.0);
}
catch (const char*s)
{
std::cout << s <<std::endl; // will get const char *error = "b is zero do not allowed " //try to use right arg
result = safe_divide(2.0,1.0);
} std::cout << result <<std::endl;
return 0;
}*/ // Use class handle the error
class ClassBad_divide_Except
{
private:
double v1;
double v2;
public:
ClassBad_divide_Except(double a=0.0,double b=0.0):v1(a),v2(b){ }
void mesg()
{
const char* mesgs = "Error divide argments :";
std::cout <<mesgs << v1<<"/"<<v2<<std::endl;
}
}; template <typename T>
T safe_divide(T const&a,T const &b)
{
if (b == )
{
const char *error = "b is zero do not allowed ";
throw ClassBad_divide_Except(a,b); //emit a class instance ClassBad_divide_Except()
}
return a/b;
} int main()
{
double result = 0.0 ;
try
{
result = safe_divide(2.0,0.0);
}
catch (ClassBad_divide_Except &did) // get class ref
{
did.mesg(); // get error message //try to use right arg
result = safe_divide(2.0,1.0);
} std::cout << result <<std::endl;
return ;
}
<7> RTTI
RTTI just compatable for a class have a virtual method
C++ 模式设计的更多相关文章
- 分享基于Entity Framework的Repository模式设计(附源码)
关于Repository模式,在这篇文章中有介绍,Entity Framework返回IEnumerable还是IQueryable? 这篇文章介绍的是使用Entity Framework实现的Rep ...
- php模式设计之 观察者模式
这是我写的<php模式设计>的第五篇.前面的四篇在不断学习不断加深认识,到了今天再看观察者模式,觉得非常容易理解.这也许就是我们积少成多的结果吧.希望还是能够不断进步. 开篇还是从名字说起 ...
- php模式设计之 适配器模式
在这个有没有对象都要高呼“面向对象”的年代,掌握面向对象会给我们带来意想不到的方便.学编程的小伙伴从开始能写几行代码实现简单功能到后来懂得将一些重复的操作组合起来形成一个“函数”,再到后来将“函数”和 ...
- php模式设计之 注册树模式
在前两篇单例模式和工厂模式后,终于迎来了最后一个基础的设计模式--注册树模式. 什么是注册树模式? 注册树模式当然也叫注册模式,注册器模式.之所以我在这里矫情一下它的名称,是因为我感觉注册树这个名称更 ...
- php模式设计之 工厂模式
承接上篇php模式设计之 单例模式,(虽然好像关系不大).今天讲述第二种基础的模式设计——工厂模式. 那么何为工厂模式? 从名字来看,似乎看不出什么端倪.工厂模式,和生产有关?还是和生产流程有关?难道 ...
- php模式设计之 单例模式
模式设计是什么?初学者一开始会被这高大上的名称给唬住.而对于有丰富编程经验的老鸟来说,模式设计又是无处不在.很多接触的框架就是基于各种模式设计形成的. 简单说,在写代码的过程中一开始往往接触的是面向过 ...
- JavaScript高级---门面模式设计
门面模式 两个作用: 1.简化类的接口 2.消除类与使用它的客户代码之间的耦合 门面模式常常是开发人员最亲密的朋友.它几乎是所有javascript库的核心原则 门面模式的目的是为了让开发人员用更简单 ...
- JavaScript高级---组合模式设计
一.设计模式 javascript里面给我们提供了很多种设计模式: 工厂.桥.组合.门面.适配器.装饰者.享元.代理.观察者.命令.责任链 在前面我们实现了工厂模式和桥模式 工厂模式 : 核心:为了生 ...
- JavaScript高级---桥模式设计
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...
- php模式设计之 策略模式
策略模式: 策略模式设计帮助构建的对象不必自身包含逻辑,而是能够根据需要利用其他对象中的算法. 使用场景: 例如有一个CD类,我们类存储了CD的信息. 原先的时候,我们在CD类中直接调用getCD方法 ...
随机推荐
- vue-获取dom节点
获取dom节点可以用ref属性,这个属性就是来获取dom对象的.看代码 这个属性就相当于给这个标签起了一个id样的东西 <input type="text" ref=&qu ...
- PHP6天基础知识部分
---恢复内容开始--- (一).基础(PHP超文本预处理器) 1.PHP标记(2种) 1.<?php?>:大众的用法?和php之间不能有空格否则无效. 2.<??>:小众的用 ...
- gcc编译出现dlopen、dlerror、dlsym、dlcolse的解决方法
➜ test_sqlite3 gcc *.c -I . -o xixi -pthread /tmp/cckGKTrr.o: In function `unixDlOpen': sqli ...
- Docker-02 无人值守安装 docker
#!/bin/bash # # 无人值守安装 docker # # # .关闭SELinux # setenforce sed -i 's/SELINUX=enforcinf/SELINUX=disa ...
- JDK源码之ArrayList
序言 ArrayList底层通过数组实现. ArrayList即动态数组,实现了动态的添加和减少元素 需要注意的是,容量拓展,是创建一个新的数组,然后将旧数组上的数组copy到新数组,这是一个很大的消 ...
- 【八】Spring Cloud Config
一.分布式系统面临的--配置问题 微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的力度相对较小,因此系统中会出现大量的服务.由于每个服务都需要必要的配置信息才能运行,所以一套集中式的.动 ...
- Polymer初探
Polymer是什么? Polymer英文为 n.聚合物:多聚体 网络高分子:聚合体:高分子聚合物 应用在Web组件场景, 表达的是, 一个一个小的Web组件,可以通过此框架聚合为一个 整个页面. h ...
- 十三、u-boot 调试-- NOR FLASH 支持
13.1 问题现象 在烧写进去的u-boot 中 Flash 并没有显示实际大小,需要进行修改. 13.2 问题定位过程 13.2.1 关键字搜索 Flash: 此关键字在 Board_r.c (co ...
- for-each 格式
public class D21LX { public static void main(String arge[]){ fish [] a1=new fish[3]; a1[0] = new fis ...
- JS基础题
1.三目运算符(三元条件语句)的使用方法? 条件表达式?true表达式:false表达式 2.JS数据中哪些属于引用类型? 数组.对象 引用类型变量,变量名所储存的不是变量值,而是变量所在的地址. 3 ...