vc ++ - статический член показывает ошибку - PullRequest
1 голос
/ 25 мая 2010

Я использую vc ++ (2010). Я пытаюсь создать класс для сокета на стороне сервера. Вот заголовочный файл

#include<winsock.h>
#include<string>
#include<iostream>

using namespace std;

class AcceptSocket
{
//  static SOCKET s;    
protected:

SOCKET acceptSocket;
public:
AcceptSocket(){};
void setSocket(SOCKET socket);
static void EstablishConnection(int portNo,string&);
static void closeConnection();
static void StartAccepting();
virtual void threadDeal(); 
static DWORD WINAPI MyThreadFunction(LPVOID lpParam);
};

SOCKET AcceptSocket::s;

и соответствующий исходный файл

#include<NetWorking.h>
#include<string>

void AcceptSocket::setSocket(SOCKET s)
{
acceptSocket=s;
}

void AcceptSocket::EstablishConnection(int portno,string &failure)
{
WSAData w;
int error = WSAStartup(0x0202,&w);

if(error)
    failure=failure+"\nWSAStartupFailure";

if(w.wVersion != 0x0202)
{
    WSACleanup();
    failure=failure+"\nVersion is different";
}

SOCKADDR_IN addr;

addr.sin_family=AF_INET;

addr.sin_port=htons(portno);

addr.sin_addr.s_addr=htonl(INADDR_ANY);

AcceptSocket::s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);


if(AcceptSocket::s == INVALID_SOCKET)
    failure=failure+"\nsocket creating error";

if(bind(AcceptSocket::s,(LPSOCKADDR) &addr,sizeof(addr)) == SOCKET_ERROR)
    failure=failure+"\nbinding error";

listen(AcceptSocket::s,SOMAXCONN);

}


void AcceptSocket::closeConnection()
{
if(AcceptSocket::s)
    closesocket(AcceptSocket::s);


WSACleanup();
}

void AcceptSocket::StartAccepting()
{
sockaddr_in addrNew;
int size=sizeof(addrNew);
while(1)
{
    SOCKET temp=accept(AcceptSocket::s,(sockaddr *)&addrNew,&size);
    AcceptSocket * tempAcceptSocket=new AcceptSocket();
    tempAcceptSocket->setSocket(temp);
    DWORD threadId;
    HANDLE thread=CreateThread(NULL,0,MyThreadFunction,(LPVOID)tempAcceptSocket,0,&threadId);
}
}

DWORD WINAPI AcceptSocket::MyThreadFunction(LPVOID lpParam)
{
AcceptSocket * acceptsocket=(AcceptSocket *) lpParam;
acceptsocket->threadDeal();
return 1;
}

void AcceptSocket::threadDeal()
{
"You didn't define threadDeal in the derived class";
}

Теперь main.cpp - это

#include<Networking.h>

int main()
{
}

Когда я компилирую, я получил ошибку

Error   1   error LNK2005: "private: static unsigned int AcceptSocket::s" (?s@AcceptSocket@@0IA) already defined in NetWorking.obj  C:\Documents and Settings\prabhakaran\Desktop\check\check\main.obj  check

Error   2   error LNK1169: one or more multiply defined symbols found   C:\Documents and Settings\prabhakaran\Desktop\check\Debug\check.exe 1   1   check

Что может вызвать это и как мне это решить?

Ответы [ 3 ]

3 голосов
/ 25 мая 2010

Поместите это в ваш .cpp файл вместо вашего .h файла:

SOCKET AcceptSocket::s;

Он включен во многие файлы .cpp, если он есть в вашем файле .h. И поэтому, когда вы ссылаетесь, он не знает, какой из них использовать.

0 голосов
/ 19 августа 2010

Я бы хотел уточнить, что сказал Фрэнк.Это распространенное предположение, что охрана может решить такие ошибки.Поскольку объяснение получилось немного длинным, я сделал пост в блоге, чтобы объяснить детали: http://daniel -albuschat.blogspot.com / 2010/08 / what-include-guards-in-c-are-and-what.html Надеюсь, это полезно.

0 голосов
/ 25 мая 2010

Возможно, #pragma once в самом начале вашего заголовочного файла решит проблему.

Сообщение об ошибке сообщает вам, что компоновщик находит несколько определений вашего класса, очевидно, потому что вы включаете заголовок более одного раза.

В целом это нормально, но тогда вы всегда должны добавить в свой заголовочный файл так называемые защитные приспособления , чтобы предотвратить эту ошибку.

EDIT:

Только что увидел, что ответ Брайана Р. Бонди является правильным.

...