2

我是 C++ 新手,这是我第一次使用它的类,我想知道如何调用构造函数?我已经阅读了一些关于 C++ 类的文档,这就是我想出我所拥有的东西的方式。构造函数调用私有方法来设置服务器。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sstream>
#include <string>
#include "SimpleIni.h"
#include "MySQL.cpp"
#include <thread>

class LoginServer {
    int resSocket;
    MySQL mysql;
    struct sockaddr_in strctAddr;

    private:
        void log(std::string strText, std::string strType = "INFO"){
            time_t rawtime;
            struct tm * timeinfo;
            char buffer[50];
            time(&rawtime);
            timeinfo = localtime(&rawtime);
            strftime(buffer, 50, "%c",timeinfo);
            std::cout << "[" << buffer << "][" << strType << "] > " << strText << std::endl;
        } 

        void error(std::string strError){
            log(strError, "ERROR");
            exit(1);
        }

        int setup(int intPort){
            std::stringstream objStringStream;
            objStringStream << intPort;
            log("Initializing socket server");
            resSocket = socket(AF_INET, SOCK_STREAM, 0);
            if(resSocket < 0) error("Could not create socket.");
            bzero((char *) &strctAddr, sizeof(strctAddr));
            strctAddr.sin_family = AF_INET;
            strctAddr.sin_addr.s_addr = INADDR_ANY;
            strctAddr.sin_port = htons(intPort);
            setsockopt(resSocket, SOL_SOCKET, SO_REUSEADDR, (struct sockaddr *) &strctAddr, sizeof(strctAddr));
            if(bind(resSocket, (struct sockaddr *) &strctAddr, sizeof(strctAddr)) < 0)
                error("Could not bind");
            listen(resSocket, 5);
            log("Listening for clients on " + objStringStream.str(), "FINE");
            return 1;
        }

        int sendPacket(int resSock, std::string strData){
            int intWrite;
            char chBuffer[8192];
            strcpy(chBuffer, strData.c_str());
            log("Sending packet: " + strData, "SEND");
            intWrite = write(resSock, chBuffer, strlen(chBuffer) + 1);
            return intWrite;
        }

        std::string RandomString(int len){
           srand(time(0));
           std::string str = "`~!@#$%^&*()-=_+[]\{]|;:'\",<.>/?0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
           int pos;
           int size = str.size();
           while(size != len) {
            pos = ((rand() % (str.size() - 1)));
            str.erase (pos, 1);
           }
           return str;
        }

        void handleData(int resSock, char* strData){
            char * chData;
            chData = strtok(strData, "\0");
            while(chData != NULL){
                std::string strPacket = chData;
                log("Received data: " + std::string(strPacket), "RECV");
                if(strPacket.compare("<policy-file-request/>") == 0){
                    log("Policy request received");
                    sendPacket(resSock, "<cross-domain-policy><allow-access-from domain='*' to-ports='6112'/></cross-domain-policy>");
                } else if(strPacket.compare("<msg t='sys'><body action='verChk' r='0'><ver v='153' /></body></msg>") == 0){
                    log("Version check received");
                    sendPacket(resSock, "<msg t='sys'><body action='apiOK' r='0'></body></msg>");
                }
                chData = strtok(NULL, "\0");
            }
        }

        void handleClient(int resSock){
            char chBuffer[6486];
            int intRead;
            for(;;){
                bzero(chBuffer, 6486);
                intRead = read(resSock, chBuffer, 6486);
                if(chBuffer == NULL) continue;
                if(intRead <= 0){
                    log("Client disconnected");
                    close(resSock);
                    break;
                } else {
                    handleData(resSock, chBuffer);
                }
            }
        }

        void listenToClients(){
            for(;;){
                std::stringstream objStringStream;
                struct sockaddr_in clntAddr;
                socklen_t intClients = sizeof(clntAddr);
                int resClient = accept(resSocket, (struct sockaddr *) &clntAddr, &intClients);
                if(resClient < 0) log("Failed to accept client", "ERROR");
                setsockopt(resClient, SOL_SOCKET, SO_REUSEADDR, (struct sockaddr *) &clntAddr, sizeof(clntAddr));
                char floatIP[INET_ADDRSTRLEN];
                inet_ntop(AF_INET, &clntAddr.sin_addr, floatIP, sizeof floatIP);
                objStringStream << floatIP;
                log("New client connected (IP: " + objStringStream.str() + ")");
                std::thread objThread(&LoginServer::handleClient, this, resClient);
                objThread.detach();
            }
        }

    public:
        LoginServer();
};
LoginServer::LoginServer(){
    CSimpleIniA objIniParser;
    objIniParser.LoadFile("Settings.conf");
    #define Host objIniParser.GetValue("Database", "Host", NULL)
    #define User objIniParser.GetValue("Database", "User", NULL)
    #define Pass objIniParser.GetValue("Database", "Pass", NULL)
    #define Name objIniParser.GetValue("Database", "Name", NULL)    
    if(!mysql.connect(Host, User, Pass, Name)) error("Could not establish database connection.");
    setup(6112);
    listenToClients();
}

int main(){
    LoginServer objLoginServer();
    return 0;
}
4

5 回答 5

8

由于 C++ 中的解析规则:

LoginServer objLoginServer();

不声明类型的对象LoginServer。实际上是声明了一个不带参数并按值返回对象的函数LoginServer

相反,你想说:

LoginServer objLoginServer;
于 2012-08-15T03:50:51.880 回答
3

尝试删除括号:

LoginServer objLoginServer;

如果您对发生的事情感到好奇,请搜索“最令人烦恼的解析”。

于 2012-08-15T03:51:24.307 回答
2

每次实例化对象时都应调用构造函数,例如行LoginServer objLoginServer; (提示:尝试不带括号)或LoginServer *objLoginServer = new LoginServer();,当然记得delete objLoginServer;在完成后调用。

于 2012-08-15T03:48:57.920 回答
0

http://www.cplusplus.com/doc/tutorial/classes/

阅读这篇文章是一个好的开始。祝你好运。

重要提示:请注意,如果我们声明一个新对象并希望使用其默认构造函数(没有参数的构造函数),我们不包括括号 ():

CRectangle rectb;   // right
CRectangle rectb(); // wrong! 
于 2012-08-15T03:48:44.783 回答
0

有多种调用构造函数的方法,但我想你的具体问题是你在调用默认构造函数时放置括号,你需要省略它们:LoginServer objLoginServer;

出现这样的问题是因为编译器无法区分声明函数原型和调用默认构造函数。看A B(),脱离上下文,它可能是使用默认构造函数创建具有B类型名称的对象,或者是返回类型实例的函数。ABA

于 2012-08-15T03:53:38.410 回答