C++ 函数_main中未解析的外部符号“cSocket::cSocket(void)”

C++ 函数_main中未解析的外部符号“cSocket::cSocket(void)”,c++,visual-c++,constructor,linker,C++,Visual C++,Constructor,Linker,错误:未解析的外部符号公共:\ uu thiscall cSocket::cSocketvoid??0cSocket@@QAE@XZ在函数_main中引用 怎么了?您没有声明构造函数定义 #ifndef _ClientSocket_H_ #define _ClientSocket_H_ #include "Includes.h" #include "LOGMSGs.h" class cSocket { public: cSocket(); bool Open(); b

错误:未解析的外部符号公共:\ uu thiscall cSocket::cSocketvoid??0cSocket@@QAE@XZ在函数_main中引用


怎么了?

您没有声明构造函数定义

#ifndef _ClientSocket_H_
#define _ClientSocket_H_

#include "Includes.h"
#include "LOGMSGs.h"

class cSocket
{
public:
    cSocket();
    bool Open();
    bool Listen(char *OnIP,int OnPort);
    void Send(char *MSG, int len);
    void Recv(char *MSG,int len);
    void Close();
protected:
    SOCKET  cSock;
    const int   SndBuf;
};

#endif


#include "ClientSocket.h"


bool cSocket::Open()
{
    WSADATA wsaData;
    int err;
    if((err =WSAStartup(0x202, &wsaData)) !=0)
    {
        Error("Init WSAStartup() failed[%d].", err);
        return false;
    }
    return true;
}

bool cSocket::Listen(char *OnIP,int OnPort)
{
    if(Open())
    {
        //Create the main socket
        cSock=socket(AF_INET, SOCK_STREAM, 0);
        if(cSock==INVALID_SOCKET)
        {
            int err = WSAGetLastError();
            //WSACleanup();
            printf("Init socket() failed[%d].", err);
            return FALSE;
        }

        //Set the REUSEADDR SOCKET
        int     optval = 1;
        if(setsockopt(cSock, SOL_SOCKET, SO_REUSEADDR, (char *) &optval, sizeof(optval)))
        {
            int err = WSAGetLastError();
            Close();
            printf("Init setsockopt() SO_REUSEADDR failed[%d].", err);
            return FALSE;
        }

        //Set the KEEPALIVE SOCKET
        optval = 1;
        if(setsockopt(cSock, SOL_SOCKET, SO_KEEPALIVE, (char *) &optval, sizeof(optval)))
        {
            int err = WSAGetLastError();
            Close();
            printf("Init setsockopt() SO_KEEPALIVE failed[%d].", err);
            return FALSE;
        }

            // Set the SNDBUF SOCKET
        if(SndBuf)      // Non-0: pointer SNDBUG
        {
            optval = SndBuf;
            if(setsockopt(cSock, SOL_SOCKET, SO_SNDBUF, (char *) &optval, sizeof(optval)))
            {
                int err = WSAGetLastError();
                Close();
                printf("Init setsockopt() SO_SNDBUF failed[%d].", err);
                return FALSE;
            }

            // Read the SNDBUF SOCKET
            int ret = sizeof(optval);
            if(getsockopt(cSock, SOL_SOCKET, SO_SNDBUF, (char *) &optval, &ret) == 0)
            {
                LOGMSG("send buffer size SOCKET [%d] K.", optval/1024);
            }
        }

        SOCKADDR_IN     sin;
        memset(&sin, 0, sizeof(sin));
        sin.sin_family      = AF_INET;
        sin.sin_addr.s_addr = inet_addr(OnIP);
        sin.sin_port        = htons(OnPort);
        if(bind(cSock, (LPSOCKADDR) &sin, sizeof(sin)))
        {
            int err = WSAGetLastError();
            Close();
            printf("Init bind() failed[%d].", err);
            return FALSE;
        }

        //Set to non-blocking mode
        unsigned long   i = 1;
        if(ioctlsocket(cSock, FIONBIO, &i))
        {
            int err = WSAGetLastError();
            Close();
            printf("Init ioctlsocket() failed[%d].", err);
            return FALSE;
        }

        //Listening port
        if(listen(cSock, SOMAXCONN))        // SOMAXCONN: WIN macro definition
        {
            int err = WSAGetLastError();
            Close();
            printf("Init listen() failed[%d].", err);
            return FALSE;
        }
        return true;
    }
return false;
}


void cSocket::Close()
{
    closesocket(cSock);
    WSACleanup();
}


#include "Includes.h"
#include "LOGMSGs.h"
#include "auth_proto.h"
#include "Packets.h"
#include "ClientSocket.h"


int main(int argc, char* argv[]) 
{
    cSocket sock;
    while(1)
    {
        sock.Open();
        sock.Listen("127.0.0.1",4444);
    }
    return 0;
}

如果您不想有一个构造函数,那么只需删除cSocket行;从类声明中,这是一个链接器错误,这意味着编译器已检查代码是否包含语法错误,但链接器找不到您试图在程序中某个地方调用的函数的实现。在这种情况下,它找不到的函数是

cSocket::cSocket()
{
    //your init code here
}
由于名称混乱,此函数看起来很神秘,其中编译器获取函数的源代码名,然后以允许更好的类型安全链接的方式对其进行转换。但是,您仍然可以看到,在代码处,这是函数名

__thiscall cSocket::cSocket(void)" (??0cSocket@@QAE@XZ) 
这是cSocket的构造函数。如果您注意到,代码中没有定义这个构造函数,这就是为什么链接器找不到它的实现。通过添加实现来修改代码应该有助于解决此问题

但是,更一般地说,如果您看到这样的错误,通常意味着您已通过函数原型或外部声明向编译器承诺存在某个函数或对象,但没有向链接器提供包含其定义的对象文件。造成这种情况的主要原因通常大致如下:

您原型化了一个函数,但忘记了实现它。我想这就是这里发生的事情。 您原型化了一个函数,但随后用不同的签名实现了它。例如,如果您将函数虚空MyStudioTimes原型化,但是实现该函数既可以是空函数MyFalthIt,也可以是空函数,链接器会认为这是一个过载而不是实现,并且会在链接时间而不是编译时间给您错误。 您使用该定义编译了代码,但未将其链接。如果您有一个多文件项目,然后忘记将其中一个文件作为输入传递给链接器,则可能会发生这种情况。
希望这有帮助

我这样做了,得到的结果是:错误C2512:“cSocket”:没有合适的默认构造函数available@templatetypedef是的,这很有帮助,但是如果我不想使用构造器怎么办?它一直强迫我使用它,我检查了我的代码,我使用了所有的东西,原型都是好的idk怎么了S@MixedCoder-不使用构造函数是什么意思?如果没有为类定义构造函数,C++将自动生成一个默认的初始化类的所有成员。也许这就是你想要的?@MixedCoder-我不确定我是否理解你最后的回答-这确实意味着这正是我想要的吗?我能帮你做些什么,你能说得具体一点吗?我很想帮忙,但我不认为我完全理解您遇到的问题。@templatetypedef-如果我没有使用构造函数,它会要求我创建一个,如果我尝试创建一个,它会说IntelliSense:cSocket::cSocket没有为:,提供初始值设定项,如果我使用空构造函数,它会给我上面的内容Error@MixedCoder-啊!!我想我看到了问题所在。您的类中有一个const data成员const int SndBuf。如果有const数据成员,则必须在构造函数内的成员初始化列表中对其进行初始化。然后,您可以选择在这里去掉const限定符,或者定义一个构造函数,使用如下内容设置值:cSocket::cSocketint value:SndBufvalue{…}。请注意,如果您将此值保留为常量成员,则必须使用成员初始化列表来设置此值。我已回滚您对问题所做的更改。请留下问题的代码和一切,这样如果有人在未来有同样的问题,他们可能会看到你的问题和下面的答案,这可能会帮助他们
cSocket::cSocket(void)