您的位置:首页 > 其它

点滴记录。

2016-12-09 11:22 169 查看
//基于栈的特点和堆的特点,决定了,在函数内部是否需要new.
//清栈是函数离开自动清,所以尽量用栈.但是共享数据必须new,如给多个类使用(一般共享指针).
//栈大小默认都不大.小于1m.因此,大数据,如稍大的数组,必须new(一般共享指针).
//编译器要求入栈必须确定栈的大小.可变的数组也必须new(一般用vector,数据是堆中的)
//由以上几点,可推导出特殊需求,如共享一个可变数据.那么就是vector的共享指针.

//同理在类内部,由于不能确定类对象是否会被new,还是在栈中.也要避免栈的缺点.
//共享数据必须在外部new,类只需要包含指针。
//稍大的数组,必须new,析构函数delete
//可变的数组也必须new(一般用vector,数据是堆中的)
//如果是类内部new,那么必须析构delete

//一些外部api,一般需要的是指针,是堆指针还是栈指针,还是依据上面原则。
//有一些特殊,如这个api,是一个异步的处理。异步的回调,又传出了这个指针,那么必须是new,要是堆中的。

1,windows下 ,c++ ,\n,其实还是会插入 \r\n

2.

因为系统提供的默认拷贝构造函数工作方式是内存拷贝,也就是浅拷贝。如果对象中用到了需要手动释放的对象,则会出现问题,这时就要手动重载拷贝构造函数,实现深拷贝。

下面说说深拷贝与浅拷贝:

浅拷贝:如果复制的对象中引用了一个外部内容(例如分配在堆上的数据),那么在复制这个对象的时候,让新旧两个对象指向同一个外部内容,就是浅拷贝。(指针虽然复制了,但所指向的空间内容并没有复制,而是由两个对象共用).

2.int out 的参照物的内存。所以out 是从内存写入到输出设备。 in是从外部读入到内存。

int main()
{

sales lulu=sales();
sales fun();// 从语法上看是定义了一个名为fun,返回值为sales的无参数函数。
sales lulu2=fun();
sales lulu3;
cout<<lulu.GetSalary()<<endl;
cout<<lulu2.GetSalary()<<endl;
cout<<lulu3.GetSalary()<<endl;
//lulu.Getjob(1000,3000);
return 0;
}

sales fun()
{
sales a;
return a;
}

声明为explicit的构造函数不能在隐式转换中使用

对比一下blockcode 和手工编译的命名就可以知道以后怎么处理了。



构造函数的,初始化的参数是输入构造参数的,不是说里面生成一个对象,在复制过去。

//多线程。

1)共享数据建议必须都用类封装。提供方法。可以清晰在多线程环境下进行。

3)

socket 是双向通讯

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <error.h>
#include <string.h>
#include <unistd.h>
#include <iostream>

using namespace std;

int main()
{
int status;
int socketNo[2];
status=socketpair(AF_LOCAL,SOCK_STREAM,0,socketNo);
if(status==-1)
{
//printf("error:%s",strerror(errno));
printf("hihi");
}
else
{
cout<<socketNo[0]<<socketNo[1]<<endl;
}

status=write(socketNo[1],"hi",2);
if(status==0)
{
cout<<"error wirte"<<endl;
}
else
{
cout<<status<<endl;
}

char readStr[10];

status= read(socketNo[0],readStr,10);
if(status==0)
{
cout<<"error wirte"<<endl;
}
else
{
readStr[9]=0x0;
cout<<readStr<<endl;
}

status=write(socketNo[0],"hi, tow",10);
if(status==0)
{
cout<<"error wirte"<<endl;
}
else
{
cout<<status<<endl;
}

status= read(socketNo[1],readStr,10);
if(status==0)
{
cout<<"error wirte"<<endl;
}
else
{
readStr[9]=0x0;
cout<<readStr<<endl;
}

status= read(socketNo[1],readStr,10);
if(status==0)
{
cout<<"error wirte"<<endl;
}
else
{
readStr[9]=0x0;
cout<<readStr<<endl;
}

close(socketNo[0]);
close(socketNo[1]);

}


利用socket编程。如果使用tcp/ip协议栈,不需要考虑数据丢失,重复,顺序,和溢出。

几本好书, 汇编原理, unix网络编程.effect c++.简明,详细又深入.

1)socket下(短连接)一般编写思路顺序。

1.对象成员数据和方法。 涉及的收发消息格式。send并shutdown.

2.后台线程的方法,涉及的收发消息格式。send并shutdown.

3.非阻塞下io的接收,涉及的收消息格式。receive 并function .

2)socket 下排错。

1.先检查客户和服务端的内存数据。

2)再查看socket的收发状态。

要这样

vector<Book> mybooks=bookManager.GetmyBooks();
vector<Book>::iterator ret= MyFind(mybooks.begin(),mybooks.end());

千万不能.

vector<Book>::iterator ret= MyFind(bookManager.GetmyBooks().begin(),bookManager.GetmyBooks().end());

mysql

PK:primary key 主键

NN:not null 非空

UQ:unique 唯一索引

BIN:binary 二进制数据(比text更大)

UN:unsigned 无符号(非负数)

ZF:zero fill 填充0 例如字段内容是1 int(4), 则内容显示为0001

AI:auto increment 自增

g:所谓Cenerated Column,就是数据库中这一列由其他列计算而得

MySQL 数据类型中的 integer types 有点奇怪。你可能会见到诸如:int(3)、int(4)、int(8) 之类的 int 数据类型。刚接触 MySQL 的时候,我还以为 int(3) 占用的存储空间比 int(4) 要小, int(4) 占用的存储空间比 int(8) 小。

后来,参看 MySQL 手册,发现自己理解错了。

代码如下复制代码
int(M): M indicates the maximum display width for integer types.

在 integer 数据类型中,M 表示最大显示宽度。

原来,在 int(M) 中,M 的值跟 int(M) 所占多少存储空间并无任何关系。 int(3)、int(4)、int(8) 在磁盘上都是占用
4 btyes 的存储空间。说白了,除了显示给用户的方式有点不同外,int(M) 跟 int 数据类型是相同的。

另外,int(M) 只有跟 zerofill 结合起来,才能使我们清楚的看到不同之处。

代码如下复制代码
mysql> drop table if exists t;

mysql> create table t(id int zerofill);

mysql> insert into t(id) values(10);

mysql> select * from t;

+------------+

| id |

+------------+

| 0000000010 |

+------------+

mysql> alter table t change column id id int(3) zerofill;

mysql> select * from t;

+------+

| id |

+------+

| 010 |

+------+

mysql>

mysql> alter table t change column id id int(4) zerofill;

mysql> select * from t;

+------+

| id |

+------+

| 0010 |

+------+

mysql>

mysql> insert into t(id) values(1000000);

mysql> select * from t;

+---------+

| id |

+---------+

| 0010 |

| 1000000 |

+---------+

从上面的测试可以看出,“(M)”指定了 int 型数值显示的宽度,如果字段数据类型是 int(4),则:当显示数值 10 时,在左边要补上
“00”;当显示数值 100 是,在左边要补上“0”;当显示数值 1000000 时,已经超过了指定宽度“(4)”,因此按原样输出。

在使用 MySQL 数据类型中的整数类型(tinyint、smallint、 mediumint、 int/integer、bigint)时,非特殊需求下,在数据类型后加个“(M)”,我想不出有何意义。

下面补充一下数据类型

1、整型

MySQL数据类型含义(有符号)
tinyint(m)1个字节 范围(-128~127)
smallint(m)2个字节 范围(-32768~32767)
mediumint(m)3个字节 范围(-8388608~8388607)
int(m)4个字节 范围(-2147483648~2147483647)
bigint(m)8个字节 范围(+-9.22*10的18次方)
取值范围如果加了unsigned,则最大值翻倍,如tinyint unsigned的取值范围为(0~256)。

int(m)里的m是表示SELECT查询结果集中的显示宽度,并不影响实际的取值范围,没有影响到显示的宽度,不知道这个m有什么用。

2、浮点型(float和double)

MySQL数据类型含义
float(m,d)单精度浮点型 8位精度(4字节) m总个数,d小数位
double(m,d)双精度浮点型 16位精度(8字节) m总个数,d小数位
设一个字段定义为float(5,3),如果插入一个数123.45678,实际数据库里存的是123.457,但总个数还以实际为准,即6位。

3、定点数

浮点型在数据库中存放的是近似值,而定点类型在数据库中存放的是精确值。

decimal(m,d) 参数m<65 是总个数,d<30且 d<m 是小数位。

4、字符串(char,varchar,_text)

MySQL数据类型含义
char(n)固定长度,最多255个字符
varchar(n)固定长度,最多65535个字符
tinytext可变长度,最多255个字符
text可变长度,最多65535个字符
mediumtext可变长度,最多2的24次方-1个字符
longtext可变长度,最多2的32次方-1个字符
5.一个大坑。

使用类库,类库尽量不要存在静态变量。非要使用,静态变量的定义在类库项目中。

尽量在大思路,大框架基本无盲点后开始项目开发。

如果时间紧迫,也必须在开发模块时,

1)把模块的输入,输出压缩到最小,

2)复杂的需求,分开做出几个模块,不要做大而全的模块。特别是在需求会变或全新的项目下。

保证项目过程中的思路,框架的变更后,原有模块可以完美适用。

不然,修改模块是一个很耗费时间和测试的工作。切记!!!!!!!!!!!!!!!!!!!!!!!!!!!

写模块时,先从主输入输出模块写起。回调或委托先写好,这样,功能铺开时,才好处理。各功能间的接口,参数就好确定。

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

[b]所以最佳实践:对象的创建,必须明确,仅仅是局部使用,还是会传出去,局部使用,就可以直接在栈中,如果会传出去(或返回,或包含在返回对象中),必须传递对象,或者堆中的地址(智能指针)[/b]

修改一些bug,或添加新功能时候,非常有必要一个一个来完整的修改测试。不然,一遍一遍的检查是否完成, 修改完一个更新一个。难得可以先跳过。但不要做到一半!!!!!!!!!,切记。

[b]内存对齐:[/b]

[b]3规则[/b]

[b]:第一个从0开始。[/b]

[b]二:每个从自身的整数倍开始。[/b]

[b]三,最后收尾按最大的类型的整数倍。[/b]

[b]所以感觉随意一点就只要先写最小的。大的放最后,非要完全节省,就要细细摆了。感觉这个是编译器的事情。不用太关注。[/b]

class S

{

int i;//0.3 第一规则

short s[5];//4.13

char c;//14 补 到4的倍数, 14-15第三规则

};

class D

{

char c0;//0-0

double d[3];//8-31第二规则

char c;//32 补 到8的倍数, 32-39第三规则

};



[b]文件的操作。[/b]

[b]常用就3种模式[/b]

[b]附加:fstream fs(filepath.c_str(),ios_base::app|ios_base::out);[/b]

[b]覆盖:fstream fs(filepath.c_str(),ios_base::out);[/b]

[b]读起: ifstream fin; fin.open(filepath.c_str(),ios::in);[/b]

[b]二维数组[/b]

int rows=5;
int column=6;

int **array3=new int*[rows];

for(int i=0;i<rows;++i)
{
array3[i]=new int[column];
}

array3[2][3]=5;

for(int i=0;i<rows;++i)
{
delete[] array3[i];
}
delete[] array3;

int* array2=new int[rows*column];

array2[0]=1;
array2[0+1]=2;

array2[1+0]=2;

for(int i=0;i<rows;++i)
{
for(int j=0;j<column;++j)
{
cout<<i*column+j;
array2[i*column+j]=i*10+j;
}
cout<<endl;
}

for(int i=0;i<30;++i)
{
cout<<array2[i]<<endl;
}

delete[] array2;


位运算符作用于位,并逐位执行操作。&、 | 和 ^

& 同时为真

| 有一个为真 : 更改某位值为1

2个不同且有一个为真。 :更改某位值为0

注意到一个使用指针的指针的场景。

系统或基础类会生成一个指针,并且自己要使用到它。而使用者需要这个指针,那么可以设置一个出参,为指针的指针,来获取。这样就比较安全,简便。

1。千万不要返回局部对象的引用

[b]2.在类的成员函数中,赋值可以返回*this.因为赋值是a=b。a是左值,是一定存在且this是隐指针参。[/b]

3.如ostream& operator<<(ostream& os,const compleNumber& complexNumb), 可以返回 os。

因为 cout<<b. cout是操作符左值,是一定存在的 且os是引用参数。


4。char& Mystring::operator[](unsigned int index)

这里也是一样。this是[b][b]隐指针参。[/b][/b]

[b][b]综合所述,返回引用,一般是返回一个 引用参数,或指针参数 的全部或部分,或者局部静态变量。[/b][/b]

[b][b]本质就是要求返回的对象,离开函数后是否还存在。存在才可以用引用。[/b][/b]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: