未调用C++构造函数

C++ constructor not being called

本文关键字:构造函数 C++ 调用      更新时间:2023-10-16

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

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

LoginServer objLoginServer();

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

相反,你想说:

LoginServer objLoginServer;

尝试删除括号:

LoginServer objLoginServer;

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

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

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

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

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

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

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

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