将库内部类隐藏到客户端C ++:使用朋友?

时间:2013-05-08 21:54:04

标签: c++ networking friend

我正在尝试使用C ++在我的基本游戏引擎中开发一个网络部分,但我遇到了一个相当奇怪的问题(对我而言)。

我有一个处理套接字(UDP)设置的Singleton Networker类,并尝试注册客户端提供给服务器的用户名,返回一个bool,表示用户名是否已被其他玩家占用或不。类本身不处理数据包本身,我的目标是使用Packethandler类。

问题在于我不希望客户端能够直接创建PacketHandler,因为Networker类的整个要点是提供某种接口来处理它。我的第一个想法是“将Packethandler的构造函数设为私有并创建一个Singleton”但是当然客户端仍然可以询问实例。然后我很快就“受到良好保护”,但Networker并没有扩展PacketHandler。然后我想'让我们让Networker成为PacketHandler的朋友'。到目前为止我发现的所有信息似乎都不鼓励朋友使用,所以我想知道: 我对简单网络部分的计划是否存在缺陷因此面临着这样的问题,或者我的问题首先是朋友功能存在的原因?你们对此有什么看法,你有更好的想法吗?

编辑:我的想法代码。

Packethandler.h

#ifndef FANCY_PACKET_HANDLER
#define FANCY_PACKET_HANDLER

#include <SFML/Network.hpp>

namespace fancy {
    namespace network {

        class PacketHandler 
        {
            friend class Networker;
        private:
            sf::IpAddress _hostAddress;
            sf::UdpSocket _socket;
            PacketHandler(std::string hostAdress);
        public:         
            ~PacketHandler();

            void sendPacket(const char* packet_data, const unsigned int packet_size);
            char* receivePacket();
        };

    }
}
#endif

Networker.h

#ifndef FANCY_NETWORKER
#define FANCY_NETWORKER

#include <SFML/Network.hpp>
#include <Engine/PacketHandler.h>

namespace fancy {
    namespace network {

        class Networker
        {       
        public:
            static Networker* instance();

            bool openUdpSocket(unsigned short port);

            bool registerUsername(char* username);
            char* receiveOnSocket();
        protected:
            Networker();
        private:
            static Networker* _instance;
            static PacketHandler* _packetHandler;

            const char* _username;

            sf::IpAddress _hostAddress;
            sf::UdpSocket _socket;
        };

    }
}

#endif

1 个答案:

答案 0 :(得分:2)

如果您希望提供界面并隐藏所有实施细节,您最好定义一个对用户可见的纯虚拟类(例如Networker)(例如.h -file),并在后代类(例如NetworkerImpl)中编写一个对用户不可见的实现。然后,您可以在头文件中声明一个函数(甚至是Networker类的静态方法),如Networker *CreateNetworker();(因此声明对用户可见),然后在{{中实现该函数1}}文件以及您的NetworkerImpl(以便用户看不到实现),如.cc