已定义的C ++类

时间:2015-05-16 17:38:15

标签: c++ visual-studio networking sfml

我不理解一个人的想法。我有一个名为" network.h"的头文件,并且有类功能的声明。在" network.cpp"文件我有这些功能。当想要包括" network.h"在main.cpp中编译我的项目(Microsoft Visual Studio 2007)我收到了这条消息:

network.obj : error LNK2005: "class networkClass network" (?network@@3VnetworkClass@@A) already defined in main.obj

我知道我们不能创建两个相同的变量,但在此我不知道错误。

源:

network.h

#ifndef H_NETWORK
#define H_NETWORK

    #include <string>
    #include <SFML/Network.hpp>




    struct getClientsStruct
    {
        std::string nick;
        sf::IpAddress clientIp;

    };

    getClientsStruct receiveClientIfno();

    class networkClass
    {
    public:
        void sendMyInfo();
        void bind();
        getClientsStruct receiveClientIfno();


    };

    networkClass network;


    #endif 

network.cpp

#include <SFML/Network.hpp>
#include "network.h"
#include <iostream>
#include <string>


sf::UdpSocket searchSocket;

//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!





    void sendMyInfo()
    {
        sf::UdpSocket searchSocket;


        std::string myLocalAddress = sf::IpAddress::getLocalAddress().toString();

        char dataSend[100] = "DANE.......";
        sf::IpAddress recipient = "255.255.255.255";
        unsigned short portSending = 54000;
        if (searchSocket.send(dataSend, 100, recipient, portSending) != sf::Socket::Done)
        {
            // error...
            std::cout << "Sending ERROR" << std::endl;
        }
        else
            std::cout << "Sending SUCCESSED" << std::endl;
    }

    void bind()
    {
        // bind the socket to a port
        if (searchSocket.bind(54000) != sf::Socket::Done)
        {
            std::cout << "ERROR binding" << std::endl;
        }
        else
            std::cout << "BIND success" << std::endl;

    }

    getClientsStruct receiveClientIfno()
    {
        getClientsStruct ClientInfo;
        searchSocket.setBlocking(0);
        char dataReceived[100];
        std::size_t received;
        sf::IpAddress sender;
        unsigned short portReceive;






        if (searchSocket.receive(dataReceived, 100, received, sender, portReceive) != sf::Socket::Done)
            {   // error...
                std::cout << "Receive ERROR" << std::endl;
            }



        std::cout << "Received " << received << " bytes from " << sender << " on port " << portReceive << std::endl;


        return ClientInfo;

    }

---------------------------------- EDIT ------------ -------------------------

所以,我从network.h中删除了networkClass network;并在main.cpp中声明了它。现在当我想要运行函数例如network.bind();时,我收到错误:main.obj : error LNK2019: unresolved external symbol "public: void __thiscall networkClass::bind(void)" (?bind@networkClass@@QAEXXZ) referenced in function _main

2 个答案:

答案 0 :(得分:2)

标题应包含在多个编译单元(cpp文件)中。不幸的是,在network.h中,您已定义了一个全局对象network。因此它将被多次声明(一次编译network.cpp时,另一次编译main.cpp时)。

全局变量(如果通过其他方式无法避免)应仅作为extern出现在标题中:

    extern networkClass network;  // you say this variable exist somewhere else

然后,您必须将定义放在一个cpp文件中。顺便说一句,如果你的班级不是绝对需要的,你不应该在班级标题中定义它。在main.cpp中定义它。如果你可以完全避开全局变量,那就去掉吧。

network.cpp中的另一个问题是,您的语法定义了全局类独立的全局函数。无论何时在类外定义类函数,都必须在其名称前加上类名。例如:

void networkClass::bind()  // say which class the function is a member
...

答案 1 :(得分:1)

您很可能完成了两次单独的编辑。 network.cpp的汇编,可能是main()函数的另一个汇编。

在`network.h'中,声明变量

networkClass network;

因此,如果在源main()函数中包含头network.h,则编译器会将变量network作为实例读取。

但是,在链接过程中,检测到变量网络在network.omain.o

中都是重复的

您应该在network.h

中指定
extern networkClass network;

然后在network.cpp中实例化它(如果你的意图是全局变量)。