2016-05-29 3 views
-2

Я сделал CPP и ч файл и создать классы в них, но я получил сообщение об ошибке с переопределение, такие кактипа класса переопределение в CPP файле

Ошибка 2 Ошибка C2011: «ConsoleCommandHandler»: «класс» тип переопределение C: \ Users \ Лукаш \ Desktop \ IRCClient-мастер \ Magic.cpp 7

, а также другие

ошибка 4 ошибка C2371: 'CommandHandler': переопределение; различные базовые типы C: \ Users \ Лукаш \ Desktop \ IRCClient-мастер \ Magic.cpp 62

Ошибка 9 ошибка C2084: функция 'ThreadReturn inputThread (недействительными *)' уже имеет тела C: \ Users \ Лукаш \ Desktop \ IRCClient-мастер \ Magic.cpp 100

Ошибка 14 ошибки C2027: использование неопределенного типа 'ConsoleCommandHandler' C: \ Users \ Лукаш \ Desktop \ IRCClient-мастер \ Magic.cpp 105

вот файлы

Magic.cpp

#include "Magic.h" 

void signalHandler(int signal); 


class ConsoleCommandHandler 
{ 
public: 
    bool AddCommand(std::string name, int argCount, void(*handler)(std::string /*params*/, IRCClient* /*client*/)) 
    { 
     CommandEntry entry; 
     entry.argCount = argCount; 
     entry.handler = handler; 
     std::transform(name.begin(), name.end(), name.begin(), towlower); 
     _commands.insert(std::pair<std::string, CommandEntry>(name, entry)); 
     return true; 
    } 

    void ParseCommand(std::string command, IRCClient* client) 
    { 
     if (_commands.empty()) 
     { 
      std::cout << "No commands available." << std::endl; 
      return; 
     } 

     if (command[0] == '/') 
      command = command.substr(1); // Remove the slash 

     std::string name = command.substr(0, command.find(" ")); 
     std::string args = command.substr(command.find(" ") + 1); 
     int argCount = std::count(args.begin(), args.end(), ' '); 

     std::transform(name.begin(), name.end(), name.begin(), towlower); 

     std::map<std::string, CommandEntry>::const_iterator itr = _commands.find(name); 
     if (itr == _commands.end()) 
     { 
      std::cout << "Command not found." << std::endl; 
      return; 
     } 

     if (++argCount < itr->second.argCount) 
     { 
      std::cout << "Insuficient arguments." << std::endl; 
      return; 
     } 

     (*(itr->second.handler))(args, client); 
    } 

private: 
    struct CommandEntry 
    { 
     int argCount; 
     void(*handler)(std::string /*arguments*/, IRCClient* /*client*/); 
    }; 

    std::map<std::string, CommandEntry> _commands; 
}; 

ConsoleCommandHandler commandHandler; 

void msgCommand(std::string arguments, IRCClient* client) 
{ 
    std::string to = arguments.substr(0, arguments.find(" ")); 
    std::string text = arguments.substr(arguments.find(" ") + 1); 

    std::cout << "To " + to + ": " + text << std::endl; 
    client->SendIRC("PRIVMSG " + to + " :" + text); 
}; 

void joinCommand(std::string channel, IRCClient* client) 
{ 
    if (channel[0] != '#') 
     channel = "#" + channel; 

    client->SendIRC("JOIN " + channel); 
} 

void partCommand(std::string channel, IRCClient* client) 
{ 
    if (channel[0] != '#') 
     channel = "#" + channel; 

    client->SendIRC("PART " + channel); 
} 

void ctcpCommand(std::string arguments, IRCClient* client) 
{ 
    std::string to = arguments.substr(0, arguments.find(" ")); 
    std::string text = arguments.substr(arguments.find(" ") + 1); 

    std::transform(text.begin(), text.end(), text.begin(), towupper); 

    client->SendIRC("PRIVMSG " + to + " :\001" + text + "\001"); 
} 

ThreadReturn inputThread(void* client) 
{ 
    std::string command; 

    commandHandler.AddCommand("msg", 2, &msgCommand); 
    commandHandler.AddCommand("join", 1, &joinCommand); 
    commandHandler.AddCommand("part", 1, &partCommand); 
    commandHandler.AddCommand("ctcp", 2, &ctcpCommand); 

    while (true) 
    { 
     getline(std::cin, command); 
     if (command == "") 
      continue; 

     if (command[0] == '/') 
      commandHandler.ParseCommand(command, (IRCClient*)client); 
     else 
      ((IRCClient*)client)->SendIRC(command); 

     if (command == "quit") 
      break; 
    } 

#ifdef _WIN32 
    _endthread(); 
#else 
    pthread_exit(NULL); 
#endif 
} 

magic.h

#ifndef Magic_h 
#define Magic_h 
#include <iostream> 
#include <signal.h> 
#include <cstdlib> 
#include <map> 
#include <algorithm> 
#include "src\Thread.h" 
#include "src\IRCClient.h" 



volatile bool running; 

void signalHandler(int signal) 
{ 
    running = false; 
} 

class ConsoleCommandHandler 
{ 
public: 
    bool AddCommand(std::string name, int argCount, void(*handler)(std::string /*params*/, IRCClient* /*client*/)); 
    void ParseCommand(std::string command, IRCClient* client); 
private: 
    struct CommandEntry 
    { 
     int argCount; 
     void(*handler)(std::string /*arguments*/, IRCClient* /*client*/); 
    }; 

    std::map<std::string, CommandEntry> _commands; 
}; 
ConsoleCommandHandler commandHandler; 

void msgCommand(std::string arguments, IRCClient* client) 
{ 
    std::string to = arguments.substr(0, arguments.find(" ")); 
    std::string text = arguments.substr(arguments.find(" ") + 1); 

    std::cout << "To " + to + ": " + text << std::endl; 
    client->SendIRC("PRIVMSG " + to + " :" + text); 
}; 

void joinCommand(std::string channel, IRCClient* client) 
{ 
    if (channel[0] != '#') 
     channel = "#" + channel; 

    client->SendIRC("JOIN " + channel); 
} 

void partCommand(std::string channel, IRCClient* client) 
{ 
    if (channel[0] != '#') 
     channel = "#" + channel; 

    client->SendIRC("PART " + channel); 
} 

void ctcpCommand(std::string arguments, IRCClient* client) 
{ 
    std::string to = arguments.substr(0, arguments.find(" ")); 
    std::string text = arguments.substr(arguments.find(" ") + 1); 

    std::transform(text.begin(), text.end(), text.begin(), towupper); 

    client->SendIRC("PRIVMSG " + to + " :\001" + text + "\001"); 
} 

ThreadReturn inputThread(void* client) 
{ 
    std::string command; 

    commandHandler.AddCommand("msg", 2, &msgCommand); 
    commandHandler.AddCommand("join", 1, &joinCommand); 
    commandHandler.AddCommand("part", 1, &partCommand); 
    commandHandler.AddCommand("ctcp", 2, &ctcpCommand); 

    while (true) 
    { 
     getline(std::cin, command); 
     if (command == "") 
      continue; 

     if (command[0] == '/') 
      commandHandler.ParseCommand(command, (IRCClient*)client); 
     else 
      ((IRCClient*)client)->SendIRC(command); 

     if (command == "quit") 
      break; 
    } 

#ifdef _WIN32 
    _endthread(); 
#else 
    pthread_exit(NULL); 
#endif 
} 
#endif 
+1

Это не C. Пожалуйста, не добавляйте несвязанные теги. –

+1

Что вы определяете класс снова в .cpp файле? У вас уже есть определение в заголовке, которое вы '# include'd. Вам нужно только определить его функции-члены - например: bool ConsoleCommandHandler :: AddCommand (...) {...} ' –

+0

приятно видеть фактические сообщения об ошибках в вопросе.Проблема очень проста, поэтому эта [ссылка] (http://www.learncpp.com/cpp-tutorial/89-class-code-and-header-files/) дает разумное объяснение классов в заголовках и исходных файлах , – stefaanv

ответ

0

Проблема заключается в том, что вы определяете класс как в .cpp и .h файл. Помните, когда вы # включаете что-то, компилятор просто заменяет директиву #include содержимым файла. Так что ваш файл «Magic.cpp» выглядит примерно так:

//// from Magic.h 
#ifndef Magic_h 
#define Magic_h 
#include <iostream> 
#include <signal.h> 
#include <cstdlib> 
#include <map> 
#include <algorithm> 
#include "src\Thread.h" 
#include "src\IRCClient.h" 

volatile bool running; 

void signalHandler(int signal) 
{ 
    running = false; 
} 

class ConsoleCommandHandler 
{ 
// ... 
}; 
//// end of #include "Magic.h" 

void signalHandler(int signal); 

class ConsoleCommandHandler 
{ 
// ... 
}; 

У вас есть два определения одного и того же класса в том же исходном файле.

Если вы просто пытаетесь реализовать функции-члены, вы делаете это так:

// Magic.h 
class ConsoleCommandHandler 
{ 
public: 
    bool AddCommand(std::string name, int argCount, void(*handler)(std::string /*params*/, IRCClient* /*client*/)); 
    // ... 
}; 

и

// Magic.cpp 

#include "Magic.h" 

bool ConsoleCommandHandler::AddCommand(std::string name, int argCount, void(*handler)(std::string /*params*/, IRCClient* /*client*/)) 
{ 
    // implementation 
} 

--- EDIT ---

Ваши следующие проблемы с «volatile bool running» и «void signalHandler».

//// Magic.h 

volatile bool running; 

void signalHandler(int signal) 
{ 
    running = false; 
} 

Они должны идти в файл .cpp, в противном случае вы определяете их в каждом файле .cpp, который включает в .h файл. Опять же, помните: #include эффективно заменяет собой содержимое файла. Подумайте об этом на мгновение. Мы с вами знаем, что определение «signalHandler» находится в файле .h, но компилятор не - все, что он видит, это то, что вы определяете signalHandler в каждом файле cpp.

+0

Хорошо, я сделал это как kfsone. Теперь, когда я компилирую все это, я получаю как ошибки: Ошибка ошибка LNK2005: «bool volatile running» (? Running @@ 3_NC), уже определенный в IRC.obj \t C: \ Users \ Łukasz \ Desktop \ IRCClient-мастер \ Magic.obj' 'Error ошибка LNK2005: "пустота __cdecl signalHandler (целое)"(signalHandler @@ YAXH @ Z?) уже определены в IRC.obj \t C: \ Users \ Лукаш \ Desktop \ IRCClient-master \ Magic.obj' Я понятия не имею, что делать с этими вещами ... – titans

+0

У вас есть тело «signalHandler» в .h файле, вы должны поменять его на переднее объявление и переместить 'volatile bool running' также в файл cpp. – kfsone

+0

, так что вы говорите, что я должен положить его в другой файл? – titans

Смежные вопросы