Member function already defined

Started by
9 comments, last by Durfy 16 years, 8 months ago
This problem is killing me. I have a console app and four files. (main.h, main.cpp, cBot.h, cBot.cpp) I am trying to compile the program with what I think is included the right way and set up the right way, but obviously I get a C2535 error telling me the constructor of my class cIrcBot is already defined, and also I get end of file (fatal? lol!) errors.. cBot.h
Quote:

#pragma once

//header

//includes
#include <windows.h>
#include <winsock.h>
#include <iostream>
#include <string>
#include <vector>

//constants and globals
const std::string WHITESPACE = ":!~ \t\n\r";

//function prototypes
//void BotInfoToSend();
std::string ParseWord( const std::string& p_string, int p_index );

void EndBot();
void HandleChannelMsg(std::string Msg);
void HandleServerMsg(std::string Msg);
void HandlePrivateMsg(std::string Msg);

//Bot Class
class cIrcBot {
protected:
	//Member variables
	BOOL					 m_bError;
	std::string				 m_sErrorString;
	char					 m_cRcvBuff[512];
	WSADATA					 m_wsaData;
	struct hostent*			 m_heServerIP;
	struct sockaddr_in		 m_saSockAddr;
	SOCKET					 m_skDataSocket;
	std::string				 m_sUser;
	std::string				 m_sNick;
	std::vector<std::string> m_vsChannels;
	std::vector<std::string> m_vsOwners;

public:
	//constructor/destructor
	cIrcBot(std::string sUser, std::string sNick);
	virtual ~cIrcBot();

	//Accessor Methods
	const BOOL GetError() const { return m_bError; }
	const std::string GetErrorString() const { return m_sErrorString; }
	const std::string GetBotNick() const { return m_sNick; }
	const SOCKET GetSocket() const { return m_sDataSocket; }
	BOOL  InChannel() { return ((m_vsChannel[0] != "") ? TRUE:FALSE); }

	void SetNick(std::string sNick) { m_sNICK = sNick; SendToIrc("NICK " + m_sNICK);
	void AddOwner(std::string sOwner) { m_vsOwners.push_back(sOwner); }

	//IrcBot Functions
	void Connect(char* cServerName, unsigned short usPort);
	void Unconnect();
	std::string GetAuthName( const std::string& AuthNameString);
	std::string GetRecv();
	void SendToIrc(std::string IrcString);
	bool CheckOwners();
	void JoinChannel(std::string sChannelName);
	void LeaveChannel(std::string sChannelName);
	//void Log(char* cFilename, std::string sContent);
};
cBot.cpp
Quote:

#include "cBot.h"

cIrcBot::cIrcBot(std::string sUser, std::string sNick )
{
	m_sUser = sUser;
	m_sNick = sNick;
	m_bError = FALSE;
}

cIrcBot::~cIrcBot()
{
}

void cIrcBot::Connect(char* cServerName, unsigned short usPort)
{
	
	//let the bot only connect to one server
	//startup winsock
	if(!(WSAStartup(MAKEWORD(2,2), &m_wsaData)))
	{
		m_sErrorString = "WSA failed to initialize";
		m_bError = TRUE;
	}

	//create the socket
	if ((m_skDataSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == NULL)
	{
		m_sErrorString = "Socket failed to create";
		m_bError = TRUE;
	}

	//get the server IP
	m_heServerIP = gethostbyname(cServerName);
	//set the properties of the sockaddr structure
	m_saSockAddr.sin_family = AF_INET;
	m_saSockAddr.s_addr = *((unsigned long*)m_heServerIP->h_addr_list[0]);
	m_saSockAddr.sin_port = htons(usPort);
	memset(m_saSockAddr.sin_zero, 0, 8);

	//connect to irc server
	if (!(connect(m_skDataSocket, &m_saSockAddr, sizeof(m_saSockAddr))))
	{
		m_sErrorString = "Couldn't connect to the server " + cServerName + " : " + m_saSockAddr.s_addr;
		m_bError = TRUE;
	}
	
	//send Info, then get ping, then connected after that.
	Sleep(3000);				  //Sleep 3 seconds : to wait for server response
	SendToIrc("NICK " + m_sNick); //Send the nickname
	SendToIrc(m_sUser);			  //Send the user
	//as for special modes and auth's, needs to be put in right after connection to work properly
	std::cout << "Connected to server : " << cServerName << std::endl;
}

void cIrcBot::Unconnect()
{
	//Leave all channels
	LeaveChannel("0");

	//Shutdown winsock
	shutdown(m_skDataSocket, 2);
	closesocket(m_skDataSocket);
	WSACleanup();
}

std::string cIrcBot::GetRecv()
{
	recv(m_skDataSocket, m_cRcvBuff, 512, 0);
			
	for (int i = 0; i<512; i++)
	{
		if (i == 511)			//to prevent overflow, end the string early if near end of length
			m_cRcvBuff[512] = '\0';
		else if (m_cRcvBuff == '\n')
			m_cRcvBuff[i++] = '\0';
	}

	return m_cRcvBuff;
}

void cIrcBot::SendToIrc(std::string IrcString)
{
	//check to see if last character is \n, to be registered by the server
	if (IrcString.substr(IrcString.length()-1, IrcString.length()) != "\n") 
		IrcString += "\n";
	send(m_skDataSocket, IrcString.c_str(), IrcString.length(), 0);
}

void cIrcBot::JoinChannel(std::string sChannel)
{
	SendToIrc("JOIN " + sChannel);
	m_vsChannels.push_back(sChannel);
}

void cIrcBot::LeaveChannel(std::string sChannelName)
{
	for (int i = 0; i < m_vsChannels.length; i++)
	{
		if ( m_vsChannels == sChannelName )
		{
			SendToIrc("PART " + sChannelName);
			m_vsChannels.erase(i);
			break;
		}
		//ability to leave all channels
		else if (sChannelName == "0")
		{
			SendToIrc("PART " + m_vsChannels);
			m_vsChannels.erase(i);
		}
	}
}


std::string cIrcBot::GetAuthName(const std::string& AuthNameString)
{
	const std::string ParseObjects = "@.";
	
	short start = AuthNameString.find_first_of(ParseObjects);
		  start = AuthNameString.find_first_not_of(ParseObjects, start);
	short end = AuthNameString.find_first_of(ParseObjects, start);
	
	return AuthNameString.substr(start, end - start);
}

bool cIrcBot::CheckOwners()
{
	std::string AuthCheck = m_cRcvBuff;
	for (int i=0; i<m_vsOwners.length; i++)
	{
		if (GetAuthName(ParseWord(AuthCheck,1)) == m_vsOwners)
			return true;
	}
	return false;
}

std::string ParseWord( const std::string& p_string, int p_index )
{
    int wss = p_string.find_first_not_of( WHITESPACE );

    while( p_index > 0 )
    {
        p_index--;

        // find the beginning of the next word, by finding whitespace
        // to end the current word, and then non-whitespace at the start
        // of the next word
        wss = p_string.find_first_of( WHITESPACE, wss );
        wss = p_string.find_first_not_of( WHITESPACE, wss );
    }

    // find the end of the word
    int wse = p_string.find_first_of( WHITESPACE, wss );

    if( wss == std::string::npos )
    {
        wss = 0;
        wse = 0;
    }

    return p_string.substr( wss, wse - wss );
}
main.h
Quote:

#pragma once

//includes
#include <iostream>
#include <string>
#include "cBot.h"

//globals
cIrcBot* IrcBot;
std::string g_sReceiveString;
main.cpp
Quote:

#include "main.h"

int main(int argc, char* argv[])
{
	IrcBot = new cIrcBot("USER HeroBot 8 *: HeroBot", "HeroBot");

	//Add my auth name to owners :)
	IrcBot->AddOwner("HamsterChubbz");
	IrcBot->Connect("irc.gamesurge.net", 6667);

	while (!IrcBot->GetError())
	{	//GetRecv includes the blocking functin recv(SOCKET, char*, int, int) so the program will stop and wait for it.
		g_sReceiveString = IrcBot->GetRecv();
		std::cout << g_sReceiveString << std::endl;
		//respond to ping message
		if(g_sReceiveString.find("PING :") != std::string::npos)
		{
			SendToIrc("PONG :" + g_sReceiveString.substr((g_sReceiveString.find_last_of(":")+1), (g_sReceiveString.find_last_of("\r")-1)) + "\n");
			continue;
		}
		if (IrcBot->InChannel())
		{
			if (ParseWord(g_sReceiveString, 2) == "PRIVMSG")
			{
				if (ParseWord(g_sReceiveString, 3).substr(0,1) == "#")
					HandleChannelMessage(g_sReceiveString);
				else if (ParseWord(TempBuff,3).substr(0,1) == "*")
					HandleServerMessage(g_sReceiveString);
				else
					HandlePersonalMessage();
			}
			continue;
		}
		else
		{
			Sleep(4000);
			IrcBot->JoinChannel("#heromode");
			continue;
		}
	}

	if (IrcBot->GetError())
		std::cout << IrcBot->GetErrorString() << std::endl;

	EndBot();
	return 0;
}

void HandleChannelMsg(std::string Msg)
{
	if (IrcBot->CheckOwners() &&
		Msg.find("die from matt") != std::string::npos)
		EndBot();
}

void EndBot()
{
	//disconnect from server
	IrcBot->Unconnect();

	//cleanup IrcBot
	delete IrcBot;
}

//ghost functions
void HandlePersonalMsg(std::string Msg)
{
}

void HandleServerMsg(std::string Msg)
{
}
My first thought is that I have set up the headers wrong within a console application.. I've looked through other code with similar set-ups and it has compiled just fine.. But I just dont understand why I am getting this error! I should have posted the exact error messages that I'm getting.. here they are : Compiling... cBot.cpp c:\program files\microsoft visual studio\myprojects\herobot\cbot.cpp(4) : error C2535: '__thiscall cIrcBot::cIrcBot(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char _traits<char>,class std::allocator<char> >)' : member function already defined or declared c:\program files\microsoft visual studio\myprojects\herobot\cbot.h(42) : see declaration of 'cIrcBot::cIrcBot' c:\program files\microsoft visual studio\myprojects\herobot\cbot.cpp(11) : error C2535: '__thiscall cIrcBot::~cIrcBot(void)' : member function already defined or declared c:\program files\microsoft visual studio\myprojects\herobot\cbot.h(43) : see declaration of 'cIrcBot::~cIrcBot' c:\program files\microsoft visual studio\myprojects\herobot\cbot.cpp(163) : fatal error C1004: unexpected end of file found main.cpp c:\program files\microsoft visual studio\myprojects\herobot\main.cpp(73) : fatal error C1004: unexpected end of file found Generating Code... Error executing cl.exe. [Edited by - TheyDontCallMeMatt on July 26, 2007 10:30:36 AM]
That's my opinion.
Advertisement
Maybe this is a stupid suggestion since I see you are using #pragma... But someone told me to use #define /ifndef checks to make sure that the file only gets included once... have you tried
#ifndef CBOT_H
#define CBOT_H

header class/includes here

#ENDIF


Hopefully that will solve the problem.
-durfy
I suspect since I'm building a console app and not a win32 application that I am getting these problems, maybe the #pragma once header doesnt work unless in a windows environment?

I'm not sure, I'm really reaching for conclusions...
But I'll try the traditional method..
That's my opinion.
Also I dont think #pragma is standard... I think it works for visual studio onlY?
-durfy
Wow, I left off a bracket in the cBot.h file, and I fixed it.
But now I'm getting more error codes that are easily fixed..

I'm sorry for wasting everyone's time with a simple syntax error.
That's my opinion.
was just about to say that:

void SetNick(std::string sNick) { m_sNICK = sNick; SendToIrc("NICK " + m_sNICK);


missing }
-durfy
[EDIT - Slow....[smile]]

It isn't because it is a console appliation.

It is probably because you are missing a closing brace at the end of this line:

void SetNick(std::string sNick) { m_sNICK = sNick; SendToIrc("NICK " + m_sNICK);


It thinks everything that follows is part of this function, and it buggers everything up.

HTH
Quote:Original post by TheyDontCallMeMatt
I suspect since I'm building a console app and not a win32 application that I am getting these problems, maybe the #pragma once header doesnt work unless in a windows environment?

I'm not sure, I'm really reaching for conclusions...
But I'll try the traditional method..


#pragma once works with most recent compilers, and triggers a warning or error for compilers where it doesn't. Even without these include guards your code should compile fine since cBot.h is only included once by every .cpp file.

Your error is most likely that you forget to close several { braces. For example:
void SetNick(std::string sNick) { m_sNICK = sNick; SendToIrc("NICK " + m_sNICK);

You don't have a }. That is also why the end-of-file is unexpected; your compiler still thinks you're defining a class.

EDIT: Wow, way too slow.
does #pragma once do the same thing as the inclusion guards ifndef def endif ?
thanks,
durfy
Quote:Original post by Durfy
does #pragma once do the same thing as the inclusion guards ifndef def endif ?
thanks,
durfy


Basically, yes. Some compilers compile a bit faster with #pragma once because it doesn't even open the file the next time (only a tiny bit faster). Of course it isn't guaranteed that #pragma once works by the C++ standard, so unless you know which environments your code will be compiled in you should prefer #ifndef ...

This topic is closed to new replies.

Advertisement