c++ 查缺补漏

c++句柄

win句柄保存对象的实时地址(对象消失,句柄消失)。指针保存固定地址(对象消失,内存泄漏)
超简单句柄类
指针型句柄
管理图书类句柄

c++ 枚举

enum Suit { Diamonds=1, Hearts, Clubs=1, Spades }a,b,c;
a=Diamonds;
b= Hearts;
c=Spades ;

得出结果b=2,c=2
假如定义 enum enumType1 { First=-5,Second=14,Third=10 };则枚举的上限是16-1=15(16大于最大枚举量14,且为2的幂); 枚举的下限是-8+1=-7(-8小于最小枚举量-5,且为2的幂);

C++继承相关

不能继承

构造、析构、拷贝构造、赋值函数 友元(非成员)
Class(),~Class(),Class(const & Class a);Class & operator=(const & Class a);

为什么不让继承这些函数

编译器会默认给空对象添加这些函数,如果允许继承,则与默认函数冲突覆盖而导致错误

基类析构函数为虚析构函数

pubvlic virture ~Class();
防止内存泄漏,不虚的话就没法调用B:A中B::~B()。
虚函数的作用是实现动态联编,也就是在程序的运行阶段动态地选择合适的成员函数,在定义了虚函数后,可以在基类的派生类中对虚函数重新定义,在派生类中重新定义的函数应与虚函数具有相同的形参个数和形参类型。以实现统一的接口,不同定义过程。如果在派生类中没有对虚函数重新定义,则它继承其基类的虚函数。

调用基类函数

B:A 则 A::Class();

C++重载

正常除了友元以外,h中定义为Class & operactor=(const & Class a);cpp Class & Class::operactor=(const Class & a)
但是对于+-*/等需要在函数内构建Class并返回的,则不返回引用,返回值
友元重载 ostream & operactor<<(const ostream &out,const Class & a); istream则不用const.目的是cout<<class,而不是class<<cout;

Mysql主键约束



1)LEFT JOIN或LEFT OUTER JOIN
左向外联接的结果集包括 LEFT OUTER子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值。
2)RIGHT JOIN 或 RIGHT OUTER JOIN
右向外联接是左向外联接的反向联接。将返回右表的所有行。如果右表的某行在左表中没有匹配行,则将为左表返回空值。
3)FULL JOIN 或 FULL OUTER JOIN
完整外部联接返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。


C++的socket编程例子

Client

#include <iostream>
#define _WINSOCK_DEPRECATED_NO_WARNINGS
//自行下载.h
#include "winsock2.h"
//静态加载ws1_32网络库
#pragma comment(lib,"Ws2_32.lib")

using namespace std;
/*
没包,麻烦
string DataToJson()
{
	Json::FastWriter writerinfo;
	Json::Value  writevalueinfo;

	writevalueinfo["id"] = 123;
	writevalueinfo["time"] = "2017.08.30 00:00:00";

	Json::Value  writedata;
	writedata["count"] = 1;
	writedata["name"] = "cpp";

	writevalueinfo["data"] = writedata;

	std::string strEmail = writerinfo.write(writevalueinfo);
	return strEmail;
}*/
int main()
{
	WSADATA wsd;//WSADATA变量
	//初始化套结字动态库,请求2.2版本的winSock库
	if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
	{
		cout << "WSAStartup failed" << endl;
		return 1;
	}

	//创建主机套接字,建立流式套接字,返回套接字号sHost
	//SOCKET socket(int af,int type,int protocol)
	//第一个参数 指定地址簇(TCP/IP只能是AF_INET,也可写为PF_INET)
	//第二个参数,选择套接字的类型(流式),第三个,特定地址家族相关协议(0:自动,TCP:IPPROTO_TCP)
	SOCKET sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (INVALID_SOCKET == sHost)
	{
		cout << "socket failed" << endl;
		WSACleanup();//释放套接字资源
		return -1;
	}

	cout << "欢迎使用CN客户端
输入quit退出" << endl;
	//设置服务器地址
	SOCKADDR_IN addrServ;
	addrServ.sin_family = AF_INET;
	addrServ.sin_addr.s_addr = inet_addr("127.0.0.1");
	addrServ.sin_port = htons(4999);
	int nAddrServLen = sizeof(addrServ);

	//连接服务器
	//int connect(SOCKET s,const struct sockaddr* name,int nameLen)
	//第一个参数:需要连接的套接字
	//第二个参数:设定所需连接的地址信息
	//第三个参数:地址的长度
	int retVal = connect(sHost, (LPSOCKADDR)&addrServ, sizeof(addrServ));
	if (SOCKET_ERROR == retVal)
	{
		cout << "connect failed!" << endl;
		closesocket(sHost);//关闭套接字
		WSACleanup();//释放套接字资源
		return -1;
	}

	const int BUF_SIZE = 1024;//64
	//接受数据缓存区
	char bufRecv[BUF_SIZE];
	//接收服务器端的欢迎信息
	ZeroMemory(bufRecv, BUF_SIZE);
	recv(sHost, bufRecv, BUF_SIZE, 0);
	cout << endl << bufRecv << endl;

	char sendBuf[BUF_SIZE];
	//发送数据缓冲区
	while (true)
	{
		//向服务器发生数据
		ZeroMemory(sendBuf, BUF_SIZE);
		cout << "向服务器发生数据" << endl;
		cin.getline(sendBuf, BUF_SIZE);
		if (0 == strlen(sendBuf))
		{
			continue;
		}
		else if (_strcmpi(sendBuf, "quit") == 0)
		{
			break;
		}

		retVal = send(sHost, sendBuf, strlen(sendBuf), 0);
		if (SOCKET_ERROR == retVal)
		{
			cout << "sent failed!" << endl;
			closesocket(sHost);//关闭套接字
			WSACleanup();//释放套接字资源
			return -1;
		}
		ZeroMemory(bufRecv, BUF_SIZE);
		recv(sHost, bufRecv, BUF_SIZE, 0);
		cout << endl << "从服务器接收数据" << bufRecv << endl;
	}
	//退出
	closesocket(sHost);//关闭套接字
	WSACleanup();//释放套接字资源

	return 0;
}

Server

#include <iostream>
#define _WINSOCK_DEPRECATED_NO_WARNINGS
//自行下载.h
#include "winsock2.h"
//静态加载ws1_32网络库
#pragma comment(lib,"Ws2_32.lib")

using namespace std;

int main()
{
	WSADATA wsd;//WSADATA变量
	//初始化套结字动态库,请求2.2版本的winSock库
	if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
	{
		cout << "WSAStartup failed" << endl;
		return 1;
	}

	//创建服务器套接字,建立流式套接字,返回套接字号sockSrv
	//SOCKET socket(int af,int type,int protocol)
	//第一个参数 指定地址簇(TCP/IP只能是AF_INET,也可写为PF_INET)
	//第二个参数,选择套接字的类型(流式),第三个,特定地址家族相关协议(0:自动,TCP:IPPROTO_TCP)
	SOCKET sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (INVALID_SOCKET == sServer)
	{
		cout << "socket failed" << endl;
		WSACleanup();//释放套接字资源
		return -1;
	}
	//struct sockaddri { u_short sa_family; char sa_datal[14]; };
	//sa_family指定该地址家族, sa_data起到占位占用一块内存分配区的作用
	//在TCP / IP中, 可使用sockaddr_in结构替换sockaddr, 以方便填写地址信息

	//struct sockaddr_in{ short sin family; unsigned short sin_port;struct in_addr sin_addr; char sin_zero[8];};
	//sin fanily表示地址族,对于IP地址,
	//sin_family成员将一直是AF_INET。
	//sin_port指定将要分配给套接字的端口。
	//sin_addr给出套接字的主机IP地址。
	//sin_zero[8]给出填充数,让sockaddr_in与sockaddr结构的长度一样。
	//将IP地址指定为INADDR_ANY,允许套接字向任何分配给本地机器的IP地址发送或接收数据。
	//如果想只让套接字使用多个IP中的一个地址,可指定实际地址,用inet_addr()函数。
	SOCKADDR_IN addrServ;//服务器地址 //服务器套接字地址
	addrServ.sin_family = AF_INET;
	addrServ.sin_port = htons(4999);
	addrServ.sin_addr.s_addr = INADDR_ANY;

	//绑定套接字
	//int bind (SOCKET s, const struct sockaddr* nane, int nameLen);
	//第一个参数,指定需要绑定的套接字;
	//第二个参数,指定该套接字的本地地址信息,该地址结构会随所用的网络协议的不同而不同
	//第三个参数,指定该网络协议地址的长度
	int retVal = ::bind(sServer, (LPSOCKADDR)& addrServ, sizeof(SOCKADDR_IN));
	if (SOCKET_ERROR == retVal)
	{
		cout << "bind failed!" << endl;
		closesocket(sServer);//关闭套接字
		WSACleanup();//释放套接字资源
		return -1;
	}

	//开始监听.
	//将套接字设置为监听模式(连接请求) , listen()通知TCP服务器准备好接收连接
	// int listen (SOCKET s, int backlog):
	//第一个参款指定需要设置的套接字,第二个参数为(等待连接队列的最大长度)
	retVal = listen(sServer, 10);
	if (SOCKET_ERROR == retVal)
	{
		cout << "listen failed!" << endl;
		closesocket(sServer);//关闭套接字
		WSACleanup();//释放套接字资源
		return -1;
	}
	cout << "欢迎使用CN服务端
输入quit退出" << endl;
	//接受客户端请求
	sockaddr_in addrClient;
	int addrClientLen = sizeof(addrClient);
	//客户端套接字
	//SOCKET accept( SOCKET s, struct sockaddr* addr, int* addrLen);
	//第一个参款,接收一个处于监听状态下的套接字
	//第二个參款,sockaddr用手保存客户端地址的信息
	//第三个参数,用于指定这个地址的长度
	//返回的是向与这个监听状态下的套接字通信的套接字
	SOCKET sClient = accept(sServer, (sockaddr FAR*)&addrClient, &addrClientLen);
	if (INVALID_SOCKET == sClient)
	{
		cout << "accept failed!" << endl;
		closesocket(sServer);//关闭套接字
		WSACleanup();//释放套接字资源
		return -1;
	}
	//发送欢迎信息
	const int BUF_SIZE = 1024;//64
	char sendBuf[BUF_SIZE];//返回客户端的数据
	cout << "ip为" << inet_ntoa(addrClient.sin_addr) << "连接到服务器" << endl;
	sprintf_s(sendBuf, "欢迎登录CN
您的ip%s
", inet_ntoa(addrClient.sin_addr));

	//发送显示欢迎信息
	int byteCount;
	if ((byteCount = send(sClient, sendBuf, strlen(sendBuf) + 1, 0)) == -1)
	{
		fprintf(stderr, "Error sending data %d
", errno);
		return -1;
	}
	printf("Sent byte %d
", byteCount);

	char receiveBuf[BUF_SIZE];//接受数据缓冲区
	while (true)//不断等待客户请求的到来
	{
		//接收客户端数据
		ZeroMemory(receiveBuf, BUF_SIZE);
		// recv(),在套接字上接收数据 
		// int recv( SOCKET s, char* buf, int len, int flags)
		//第一个參數,建立连接后的套接字, 
		//第二个参数,接收数据 
		//第三个参数,接收数据的长度, 
		//第四个参数,一些传送参数的设置
		retVal = recv(sClient, receiveBuf, BUF_SIZE, 0);
		if (SOCKET_ERROR == retVal) 
		{
			cout << "recv failed!" << endl;
			closesocket(sServer); //关闭套接字 
			closesocket(sClient); //关闭套接字
			WSACleanup();//释放套接字资源;
			return -1;
		}
		if (receiveBuf[0] == '0') 
		{
			break;
		}
		cout << "客户端发送的数据: " << receiveBuf << endl;
		cout << "向客户端发送数据: " << endl;

		cin.getline(sendBuf, BUF_SIZE);
		if (_strcmpi(sendBuf, "quit") == 0) 
		{
			break;
		}
		// send(),在套接字上发送数据
		//int send( SOCKET s, const char* buf, int len, int flags);
		//第一个参数,需要发送信息的套接字
		//第二个参數,包含了需要被传送的数据
		//第三个参数是buffer的数据长度, 
		//第四个參数,一些传送参数的设置
		send(sClient, sendBuf, strlen(sendBuf), 0);
	}
	//退出
	closesocket(sServer); //关闭套接字 
	closesocket(sClient); //关闭套接字
	WSACleanup();//释放套接字资源;
	return 0;
}

原文地址:https://www.cnblogs.com/hyry/p/10668202.html