博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
笔记草稿。
阅读量:5070 次
发布时间:2019-06-12

本文共 14372 字,大约阅读时间需要 47 分钟。

 

 

#include <iostream>

#include "..\testa\lS_utinity.h"
#include <list>
#include <vector>
#include "stdio.h"
#include <map>

//代理类,可以默认,就可以用对象数组,成员为指针,可以为0.有copy3件套.代理行为,检测0,

//什么时候需要写继承.感觉应该必须满足一个条件.就是需要多态.如果不需要多态.就算是is a,关系.也没有必要非整出一个基类.
//只要继承,就会使用指针来表示多态.只要有指针,就必须用代理类.
//所以只要继承就必须代理.

using namespace std;

class vehicle
{
public:
virtual double weight()=0;
virtual void start()=0;
};

class bike:public vehicle

{
public:
double weight();
void start();
};

class bus:public vehicle

{
public:
double weight();
void start();
};

class car:public vehicle

{
public:
double weight();
void start();
};

double bike::weight()

{
return 200;
}
void bike::start()
{

}

double bus::weight()

{
return 2000;
}
void bus::start()
{

}

double car::weight()
{
return 400;
}
void car::start()
{

}

class pm

{
public:
pm(vehicle*);
vehicle* getP();
~pm();
private:
pm();
pm(const pm&);
pm operator=(const pm&);
vehicle * pveh;
};

pm::pm(vehicle* _p):pveh(_p){}

pm::~pm(){delete pveh;}
vehicle* pm::getP(){return pveh;}

//一,对于单资源(狭义上就是内存,再狭义就是堆内存)的使用和管理.
//1,资源的建立和托管必须是一个步骤.2)托管对象必须保证和资源同生死.
//对于栈内存,.bike mybike1; 对于堆内存.bike * mybike2=new bike();
//第一种,很可靠.
//第二种,需要显示维护内存,和保护指针变量.所以引出一条款(effect c++),用对象管理资源.
//而资源管理对象和资源同生死.就必须保证资源建立和对象建立是原子操作.也是另一条款.
//并且资管,由于资源入对象是原操,那么资管必须负责资源的delete.
//1)资管必须负责资源的delete.
//2)负责delete,也就必须考虑资源copy三函数,构造,赋值,析构.
//3)资管可以没有默认的构造函数,
//4)可以直接用方法提供只读的资源地址,供外部使用
//对于第2条.如果是资源地址copy.资管转化为智能指针类.
//如果是资源copy.提供正确的构造,赋值,析构.
//如果是禁止资源copy,构造,赋值,析构.设置为private.
//如果是资源转移.提供正确的构造,赋值,析构.

//所以最终对于单资源的资源的使用.在c++中有2种比较可靠的方法.
//1)栈内存, bike mybike1;
//2)堆内存,pm mypm(new bike());

//对于多资源的统一使用和管理.

//基本是对于含有继承关系的对象而言.没有继承关系,谈不上统一管理.
//那么必须是管理指针.参考上面分析.必须建立对象.
//那么必须要求资源有默认的构造函数.

 

void showWeight(vehicle * _p)

{
cout<<_p->weight()<<endl;
}

int main()

{
//地址copy,使用智能指针类.
bike mybike1;
cout<<"**auto p***"<<endl;
showWeight(&mybike1);

//地址copy,使用智能指针类.

cout<<"**copy p***"<<endl;
pm_copyP<bike> mypm(new bike());
pm_copyP<bike> mypm2=mypm;
pm_copyP<bike> mypm3(new bike());
mypm3=mypm;

showWeight(mypm.getP());

showWeight(mypm2.getP());
showWeight(mypm3.getP());

//禁止copy值或地址.使用禁止类.

cout<<"**forbiden***"<<endl;
pm_forbidP<bike> mypm4(new bike());
showWeight(mypm4.getP());
//pm_forbidP<bike> mypm5=mypm4;//禁止复制,赋值.

//value copy,使用value-copy类.

cout<<"**copy value***"<<endl;
pm_copyValue<bike> mypm5(new bike());
pm_copyValue<bike> mypm6=mypm5;
pm_copyValue<bike> mypm7(new bike());
mypm7=mypm5;

showWeight(mypm5.getP());

showWeight(mypm6.getP());
showWeight(mypm7.getP());

//转移资源所有权, 使用transforP类. 这个和其他有不同.使用指针必须先判断,指针是否已经转移,为0了.

cout<<"**transforP***"<<endl;
pm_transforP<bike> mypm8(new bike());
pm_transforP<bike> mypm9=mypm8;
pm_transforP<bike> mypm10(new bike());
mypm10=mypm8;

if(mypm8.getP()!=0)

{
showWeight(mypm8.getP());
}
if(mypm9.getP()!=0)
{
showWeight(mypm9.getP());
}
if(mypm10.getP()!=0)
{
showWeight(mypm10.getP());
}

 

// vehicle* allCar[100]={0};

//
// bike mybike1;
// bus mybus1;
// car mycar1;
//
// allCar[0]=&mybike1;//这里是函数内,如果是外部参数,那么会有悬指针问题.所以条款,对象管理资源很必要.
// allCar[1]=&mybus1;
// allCar[2]=new car;//这里必须管理内存.
//
//
// for(int i=0;i!=100;++i)
// {
// if(allCar[i]!=0)
// {
// cout<< allCar[i]->weight()<<endl;
// }
// }

 

return 0;

}

 

 

 

#ifndef LS_UTINITY_H_INCLUDED#define LS_UTINITY_H_INCLUDED#include 
#include
#include
using namespace std;//智能指针template
class auto_MyP{public: auto_MyP
(); auto_MyP
(T const* _p); auto_MyP
(const auto_MyP&); auto_MyP
& operator=(const auto_MyP&); T* getP()const; ~auto_MyP
(); void del();private: int * count_ref; const T* autop;};template
auto_MyP
::auto_MyP(){ autop=0x0; count_ref=new int(1);}template
auto_MyP
::auto_MyP(T const* _p){ cout<<"p con:"<<_p<
auto_MyP
::auto_MyP(const auto_MyP& _lht){ autop=_lht.autop; ++(*_lht.count_ref); count_ref=_lht.count_ref;}template
auto_MyP
& auto_MyP
::operator=(const auto_MyP& _lht){ if(this!=&_lht) { del(); this->autop=_lht.autop; *_lht.count_ref=*_lht.count_ref+1; this->count_ref=_lht.count_ref; } return *this;}template
auto_MyP
::~auto_MyP(){ del();}template
void auto_MyP
:: del(){ cout<<"false del:"<<*(this->count_ref)<<". add"<
<
count_ref)=*(this->count_ref)-1;//前后自增加,就是此语句取值是取+1变量,还是把+1给临时变量,取值去取未+1的符号变量. if(*(this->count_ref)==0) { cout<<"del:"<
<
T* auto_MyP
::getP()const{ return const_cast
(autop);}//Merge sorttemplate
list
mergeSort(const list
& source);template
list
mergeSort(const list
& source){ list
ret; if(source.size()==1) { ret=source; } else if(source.size()==2) { typename list
::const_iterator firstit=source.begin(); T firstvalue=*firstit; typename list
::const_iterator secondit=++firstit; T secondvalue=*secondit; if(firstvalue<=secondvalue) { ret=source; } else { ret.push_back(secondvalue); ret.push_back(firstvalue); } } else { unsigned int count_list=source.size(); unsigned int modN= count_list%2; unsigned int subret=count_list/2; typename list
::const_iterator it=source.begin(); list
leftS; list
rightS; for(int i=0;i!=subret+modN;++i) { leftS.push_back(*it); ++it; } for(int i=0;i!=subret;++i) { rightS.push_back(*it); ++it; } leftS=mergeSort(leftS);//lefts 传递const 引用,效率和安全,不会改动.返回对象.lefts被copy赋值函数处理. rightS=mergeSort(rightS); typename list
::const_iterator lefttop=leftS.begin(); typename list
::const_iterator righttop=rightS.begin(); while(lefttop!=leftS.end() || righttop!=rightS.end()) { // check each top if(*lefttop<=*righttop) { ret.push_back(*lefttop); ++lefttop; } else { ret.push_back(*righttop); ++righttop; } } if(lefttop!=leftS.end()) { //push no process data for(lefttop;lefttop!=leftS.end();++lefttop) { ret.push_back(*lefttop); } } else if(righttop!=rightS.end()) { for(righttop;righttop!=rightS.end();++righttop) { ret.push_back(*righttop); } } return ret; } return ret;}//template
void quickSort(vector
& source, int startIndex, int endIndex){ if(startIndex
int centerFind(const vector
& source,const T& finder){ int ret=-2; int startIndex=0; int endIndex=source.size()-1; int CenterIndex=startIndex+(endIndex-startIndex)/2; while(ret==-2) { if(CenterIndex==startIndex&&startIndex==endIndex)//1个数 { if(source[CenterIndex]==finder) { ret=CenterIndex; } else { ret=-1; } } else { if(source[CenterIndex]==finder) { ret=CenterIndex; } else if(source[CenterIndex]>finder) { endIndex=CenterIndex-1; CenterIndex=startIndex+(endIndex-startIndex)/2; if(startIndex>endIndex) { ret=-2; } } else { startIndex=CenterIndex+1; CenterIndex=startIndex+(endIndex-startIndex)/2; if(startIndex>endIndex) { ret=-2; } } } } return ret;}template
class pm_copyP{public: pm_copyP(T* _p); pm_copyP(const pm_copyP&); pm_copyP& operator=(const pm_copyP&); ~pm_copyP(); T* getP();private: pm_copyP(); T* myp; int * count_ref; del();};template
pm_copyP
::pm_copyP(T* _p):myp(_p),count_ref(new int(1)){}template
pm_copyP
::pm_copyP(const pm_copyP& _pm){ myp=_pm.myp; count_ref=_pm.count_ref; ++(*count_ref);}template
pm_copyP
& pm_copyP
::operator=(const pm_copyP& _pm){ if(&_pm!=this) { del(); myp=_pm.myp; count_ref=_pm.count_ref; ++(*count_ref); } return *this;}template
pm_copyP
::~pm_copyP(){ del();}template
pm_copyP
::del(){ --(*count_ref); if(*count_ref==0) { delete myp; delete count_ref; }}template
T* pm_copyP
::getP(){ return myp;}template
class pm_forbidP{public: pm_forbidP(T* _p); ~pm_forbidP(); T* getP();private: T* myp; pm_forbidP(); pm_forbidP(const pm_forbidP&); pm_forbidP& operator=(const pm_forbidP&);};template
pm_forbidP
::pm_forbidP(T* _p):myp(_p){}template
T* pm_forbidP
::getP(){ return myp;}template
pm_forbidP
::~pm_forbidP(){ delete myp;}template
class pm_copyValue{public: pm_copyValue(T* _p); pm_copyValue(const pm_copyValue&); pm_copyValue& operator=(const pm_copyValue&); ~pm_copyValue(); T* getP();private: T* myp; void del(); pm_copyValue();};template
pm_copyValue
::pm_copyValue(T* _p):myp(_p){}template
pm_copyValue
::pm_copyValue(const pm_copyValue& _pm):myp(new T(*_pm.myp)){}template
pm_copyValue
& pm_copyValue
::operator=(const pm_copyValue& _pm){ if(&_pm!=this) { del(); myp=new T(*_pm.myp); } return *this;}template
pm_copyValue
::~pm_copyValue(){ del();}template
void pm_copyValue
::del(){ delete myp;}template
T* pm_copyValue
::getP(){ return myp;}template
class pm_transforP{public: pm_transforP(T* _p); pm_transforP(pm_transforP&); pm_transforP& operator=(pm_transforP&); ~pm_transforP(); T* getP();private: T* myp; void del(); pm_transforP();};template
pm_transforP
::pm_transforP(T* _p):myp(_p){}template
pm_transforP
::pm_transforP(pm_transforP& _pm):myp(_pm.myp){ _pm.myp=0;//const 怎么可以修改.}template
pm_transforP
& pm_transforP
::operator=(pm_transforP& _pm){ if(this!=&_pm) { del(); myp=_pm.myp; _pm.myp=0;//const 怎么可以修改. } return *this;}template
pm_transforP
::~pm_transforP(){ del();}template
void pm_transforP
::del(){ if(myp!=0) { delete myp; }}template
T* pm_transforP
::getP(){ return myp;}#endif // LS_UTINITY_H_INCLUDED

 

 

 

关于异常:

 

#include 
#include
using namespace std;//c++,实在经验不足.感觉只能是,使用某些函数,又不想每次都检测是否返回正确.那么抛出错误.程序结束.//感觉还不如返回错误代码呢.int dev(int a,int b);int main(){ int result=0; try { result=dev(3,1); } catch(exception &e) { //提示错误,保存关键数据,程序退出 cout<
<

 

 

 关于类的数据成员和参数问题。以及const。

1)类的data member.

如果是内置类型或类的值类型,语义就是局部数据,const语义就是,在类内,一个局部常量.
如果是内置类型或类的指针或引用类型,语义就是局部的指针,指向外部数据,const语义就是,在类内,不可通过此指针修改外部数据.
如果是内置类型或类的智能指针类型.语义就是局部数据,但里面有指针指向外部数据.const语义就是,在类内,不可通过此局部数据中的指针修改外部数据.
(可以完全代替第二种,只是size为8,而第2中size是4(32system)).
如果是内置类型或类的智能指针的指针或引用类型.语义就是很大概率是你想的的太复杂了.请退化为第3种.智能指针就是为了自动释放内存.
再保存它的指针,又把问题解决方案变成了问题本身.餐巾纸的作用就是为了吃饭时,让衣服更干净.为了方便拿东西.又套一个外套,还不如拿掉餐巾纸.
但是构造函数的参数应该使用 智能指针的reference,这个时候智能指针当成一般类处理.智能指针本质就是一个类了.

总结:

值还是智能指针(指针),还是引用.
从数据库讲,

一个字段不是另一个表的key。那么就是值。否则就是引用。如果表不存在这个字读。那么就是用方法返回数据(查询其他表)

 

const还是非const?

可修改用非const.否则用const.
对于智能指针,指针不可修改用 const shared_ptr<T>,指针所指的数据不可修改用shared_ptr<const T>.

从数据库讲。如果一个字段设置了触发器,字段是只读了。那么类中。一定要是const。

2)类的constructor的参数.
如果参数是内置类型或类的值类型,语义就是会创建一个原数据的副本,压入函数体.const语义就是,此参数的数据不可修改.但可以赋值给const或非const.
如果参数是内置类型或类的指针或引用类型,语义就是引用原数据,压入原数据的指针到函数体.const语义就是此地址的指向不可修改.
如果参数是内置类型或类的智能指针类型.语义就是会创建一个原数据(包含一个指针)的副本,压入函数体.const语义就是,此参数的数据不可修改.也就是里面的地址的指向不可修改.

 

 

 

 

 

时钟周期

 
       时钟周期也称为振荡周期,定义为时钟脉冲的倒数(时钟周期就是单片机外接晶振的倒数,例如12M的晶振,它的时钟周期就是1/12us),是计算机中的最基本的、最小的时间单位。
       在一个时钟周期内,CPU仅完成一个最基本的动作。时钟脉冲是计算机的基本工作脉冲,控制着计算机的工作节奏。时钟频率越高,工作速度就越快。
 
       8051单片机把一个时钟周期定义为一个节拍(用P表示),二个节拍定义为一个状态周期(用S表示)。

 

机器周期

 
       计算机中,常把一条指令的执行过程划分为若干个阶段,每一个阶段完成一项工作。每一项工作称为一个基本操作,完成一个基本操作所需要的时间称为机器周期。8051系列单片机的一个机器周期由6个S周期(状态周期)组成。 一个S周期=2个节拍(P),所以8051单片机的一个机器周期=6个状态周期=12个时钟周期。
 
       例如外接24M晶振的单片机,他的一个机器周期=12/24M 秒;

 

指令周期

 

    执行一条指令所需要的时间,一般由若干个机器周期组成。指令不同,所需的机器周期也不同。

 

 

int main(void)

{
char buf[10];
int n = read(STDIN_FILENO, buf, 10);
write(STDOUT_FILENO, buf, n);
return 0;
}

 

输入字符,回车后。。。。。

少于等于10个ok。大于10个。后续的字符,和回车键都还在标准输出中,会认为用户敲入了命令。

 

 

 关于开发整体流程。

//对于开发的流程,个人倾向,先建模,后建表.再实际建立class.

//因为先建立表,可以更快理清类之前细节.因为建类的时候需要考虑实际数据的存放问题.
//建立类的时候,发现问题.也可以修改表.
//而建立好类,不满足表,改类就麻烦.
//再次.表的话更直观,可以先不考虑细节.从整体掌握模型的数据流是否正确.
//甚至,类中犯的错误的设计,在表中就不太会出现.如员工,和职务.表明显会有好几个.一个员工表,几个不同职务表.
//而类,可能会设计为一个类.建模错误,会导致表设计不符合表设计范式.
//但是设计表的时候也可以考虑一下类.是否需要多一个表,来表现包含关系.或继承关系.

 

再一次卡在设计流程上了。

继续卡在无数据库设计上。

有数据库设计,数据存放问题不用考虑。而无数据库,放在那里,用 vector 对象还是指针,总是感觉设计不好。用vector或智能指针。

应该还是基于分析后。关系型数据设计开路(好理解,也很熟悉),数据存放问题的话。去掉表的外键,放入外键所在的表。用vector直接存放对象。,vector自己离开作用域会自动析构。析构会调用成员的析构函数并释放堆空间。完美啊。

可以先省去内部中其他类的集合。从上往下设计下来就好,下级设计好了。再返回上级,使用下级的初始化函数,来修改上级的初始化函数或其它初始化的地方。

这样设计了数据的流向后,再从面向对象的思维,设计行为。来给数据流向取个名字。

对象间的数据存放问题。

1)如果原本数据成员都不多。那么偏向一方(其中有确定数据属于的那方)。

2)用map存储数据。类方法提供对map的真删改,查, 类本身或管理类提供逻辑,调用增删改,特别注意逻辑中含删除的操作。

 

单个数据直接放栈,如果太大用智能指针。如果是不确定的多个数据或者多个大数据。用vector就好了。甚至单个大数据也可以用vector,vector自己离开作用域会自动析构。析构会调用成员的析构函数并释放堆空间。完美啊。

定义参数值用全局const。但如果是状态返回值或者作为参数可以用enum.这样就可以限定返回的数据范围。但是枚举不能设定数据类型。比如int_8,所以在网络编程需要固定长度的时候又很尴尬。

 

模型设计的一点想法,

看了下网狐。有个设计,类之间的包含关系 ,不放指针,或智能指针。

直接放一个key.

所以设计的时候,

1.可以先设计一个对象,包含属性和方法。

2.再设计一个管理类,包含一个当前key 的最大小(根据情况,是先进先出,还是先进后出)值。 用int 记录。

一般可以用int ,取int最大值为默认值,表示下次插入的key。插入的时候用这个做key.并·--,  删除的时候,看看要删除的是不是等于 key-1.如果是,++。 所以用map的key,来当前数据库的外键。

好处是避免了指针的坏处。指针可能有移动操作,也比较危险。而用 key,自然的多。终于解决了这个疑问。

 

 

 

封装的一个含义就是类的某个或几个数据是状态数据。他的改变只由行为(方法)来改变。并提供只读的查看。

服务端和客户端同步开发。

客户端的初始化行为放入main中(之后可以由网络模块发送消息,获得消息,并回调这些方法)。

客户端的动作逻辑封装成方法(之后由网络模块发送消息,获得消息,并回调这些方法)

服务端是一个完备的系统,应该是一个可以自检,自运行的系统。客户端只是通过发送消息,改变服务端的自运行的过程中的状态值。

 

 

c#

RoomInfo selectroom = rooms.Where(s => s.room_id == (SByte)this.comboBox1.SelectedValue).Single();

where 相当于里面一个bool函数。where里面已经回调了()里面的函数。并根据bool值来决定是否加入结果集合。

 

c++ get .set 生成器。

List
inputcode = new List
(); List
outputcode = new List
(); string className = this.textBox3.Text.Trim(); inputcode = this.textBox1.Text.Split(new string[] {
"\r\n"}, StringSplitOptions.RemoveEmptyEntries).ToList(); for(int i=0;i

 

 

目的:有时候有些情况比较复杂,写完了代码。也没法确定是否完全正确。画图感觉比较复杂,只能靠测试。这个时候使用状态机分析法。就能比较好。

步骤:先写出初始行为,和输入行为,以及输入行为对应的猜想的动作,通过猜想的动作,对状态的更改,判断状态是否合理,来验证行为是否正确。
每次集合中所有状态和行为一一匹配。有新状态。就保存。
之后每次用新状态和所有行为一一匹配。直到没有新状态为止。

初始状态: r_ok,s_ok,e_in;

输入行为和对应猜想动作()

1)recv_again. r_ok
2)recv_close. r_close,cancel event
3)recv_error. del
4)send_ok. s_ok ,1)close:yes,block:yes=>s_ok 2)close:yes,block:no => s_ok 3) colse:no,block:yes=>s_ok. e_in. 4)close:no,block:no=>s_ok
5)send_block. s_block,mod e_out
6)send_err. del

 

初始状态: 下和所有输入行为产生的新状态
1:r_ok,s_ok,e_in;

1-1)=>

1-2)=>r_close,s_ok
1-3)=>del
1-4)=>r_ok,s_ok,e_in
1-5)=>r_ok,s_block,e_out
1-6)=>del
状态应该正确。所以猜想行为暂时正确。
在用得到的新状态,和所有行为一一匹配
1:r_close,s_ok
2:r_ok,s_block,e_out

1-1)=>不可能会存在的行为

1-2)=>不可能会存在的行为
1-3)=>不可能会存在的行为
1-4)=>
1-5)=>r_close,s_block, e_out
1-6)=>del

2-1)=>不可能会存在的行为

2-2)=>不可能会存在的行为
2-3)=>不可能会存在的行为
2-4)=>
2-5)=>
2-6)=>del

又得到1种新状态。所有状态是2×2×2.现在只有4种。

在用得到的新状态,和所有行为一一匹配
1:r_close,s_block, e_out
1-1)=>不可能会存在的行为
1-2)=>不可能会存在的行为
1-3)=>不可能会存在的行为
1-4)=>
1-5)=>
1-6)=>del

无任何新状态。估算下是否正确
估算下,还有剩下4种是什么情况。
1:r_ok,s_ok,e_in;
2:r_ok,s_block,e_out
3:r_close,s_ok
4:r_close,s_block, e_out
哦。因为s_ 和e_只能组合成2种。
所以就是4种。
所以我们得到了全部状态。再验证一下猜想行为就好了。
虽然很烦琐,但是可以验证遗漏的情况。

 

 

 

测试epoll的时候,客户端可以线程10个内。但是开多点socket ,100左右。这样简陋的环境。也可以测试高流量,模拟高并发。注意看服务的发送和接受是否相同大小,如果是echo测试。

还要看客户端的接受。是否有重传现象。如果客户端接收的明显比服务端发送的多。

 

如何测试epoll的代码效率。

可以简单点。客户端开1000个socket.200毫毛休息一次。说明1秒有5000条信息处理。每条信息64B。发送速度就是300/kB.

服务端,每条信息的处理休息1毫秒。说明1秒处理1000条。但是测试还是不准。所以可以调整下。用netstat 命令查看。使得接受数据越来越多为好。说明程序处理慢。

这样就可以开始优化了。单线程可以优化批量发送,批量处理。

多线程就可以开始队列,新线程处理。多线程的一般特征是网路是没有问题的。接受快,发送快。因为单独线程再处理io。但是如果程序差,那么内存会原来越小。因为网络的数据全部拉到内存中去了。但是又处理不过来。

转载于:https://www.cnblogs.com/lsfv/p/6042403.html

你可能感兴趣的文章
聚合与组合
查看>>
数据库图片存储也读取
查看>>
jQuery如何获得select选中的值?input单选radio选中的值
查看>>
粘贴板工具,剪切板工具
查看>>
设计模式 之 享元模式
查看>>
查看数据库是否有死锁
查看>>
如何理解汉诺塔
查看>>
洛谷 P2089 烤鸡【DFS递归/10重枚举】
查看>>
15 FFT及其框图实现
查看>>
Linux基本操作
查看>>
osg ifc ifccolumn
查看>>
C++ STL partial_sort
查看>>
3.0.35 platform 设备资源和数据
查看>>
centos redis 安装过程,解决办法
查看>>
IOS小技巧整理
查看>>
WebDriverExtensionsByC#
查看>>
我眼中的技术地图
查看>>
lc 145. Binary Tree Postorder Traversal
查看>>
sublime 配置java运行环境
查看>>
在centos上开关tomcat
查看>>