c++ 查缺補漏

c++句柄

win句柄保存對象的實時地址(對象消失,句柄消失)。指針保存固定地址(對象消失,內存泄漏)
超簡單句柄類
指針型句柄
管理圖書類句柄html

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的冪);mysql

C++繼承相關

不能繼承

構造、析構、拷貝構造、賦值函數 友元(非成員)
Class(),~Class(),Class(const & Class a);Class & operator=(const & Class a);ios

爲何不讓繼承這些函數

編譯器會默認給空對象添加這些函數,若是容許繼承,則與默認函數衝突覆蓋而致使錯誤c++

基類析構函數爲虛析構函數

pubvlic virture ~Class();
防止內存泄漏,不虛的話就無法調用B:A中B::~B()。
虛函數的做用是實現動態聯編,也就是在程序的運行階段動態地選擇合適的成員函數,在定義了虛函數後,能夠在基類的派生類中對虛函數從新定義,在派生類中從新定義的函數應與虛函數具備相同的形參個數和形參類型。以實現統一的接口,不一樣定義過程。若是在派生類中沒有對虛函數從新定義,則它繼承其基類的虛函數。sql

調用基類函數

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客戶端\n輸入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服務端\n輸入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\r\n您的ip%s\r\n", inet_ntoa(addrClient.sin_addr));

    //發送顯示歡迎信息
    int byteCount;
    if ((byteCount = send(sClient, sendBuf, strlen(sendBuf) + 1, 0)) == -1)
    {
        fprintf(stderr, "Error sending data %d\n", errno);
        return -1;
    }
    printf("Sent byte %d\n", 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;
}
相關文章
相關標籤/搜索