没有调用C ++构造函数

时间:2012-08-15 03:44:54

标签: c++ syntax constructor variable-declaration most-vexing-parse

我是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;
}

5 个答案:

答案 0 :(得分:6)

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

LoginServer objLoginServer();

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

相反,你想说:

LoginServer objLoginServer;

答案 1 :(得分:2)

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

答案 2 :(得分:2)

尝试删除括号:

LoginServer objLoginServer;

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

答案 3 :(得分:0)

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

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

重要说明:请注意如果我们声明一个新对象并且我们想要使用它的默认构造函数(没有参数的那个),我们不包括括号():

CRectangle rectb;   // right
CRectangle rectb(); // wrong! 

答案 4 :(得分:0)

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

出现这样的问题是因为编译器无法在声明函数原型和调用默认构造函数之间进行distingush。查看A B(),在上下文之外,它可能正在使用默认构造函数创建类型为B的名称为A的对象,或者函数B返回类型为{{1}的实例}。