在类之间共享成员函数 [英] Sharing member functions between classes

查看:45
本文介绍了在类之间共享成员函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在设计一个应用程序,该应用程序使用一个类来管理TCP连接,并使用一个类来管理UI元素.连接管理器接收消息字符串,并对其进行最少的处理以确定它们的类型.如果它们是已知类型,则连接管理器会将字符串传递给GUI管理器,以便可以相应地更新UI元素.

I'm designing an application that uses one class to manage a TCP connection and one to manage UI elements. The connection manager receives message strings and does minimal processing on them to determine their type. If they're of a known type, the connection manager will pass the strings along to the GUI manager so it can update the UI elements accordingly.

我的挑战是:如果我不想跨类包含头文件,如何允许访问另一个类的公共函数?

My challenge is this: if I don't want to include header files across classes, how do I permit access to the other class's public functions?

例如:

//message_types.h
typedef void(*MessageHandlerPointer)(std::string);

enum MessageTypes { info_type, time_type, command_type, reply_type,
                    inside_type, update_type, NUM_TYPES };
/////////////////////////////////////////////////////////////////////////
//ConnectionManager.h
class ConnectionManager
{
  string hostname;
  string port;
  int connection_fd;

  string message_types[NUM_TYPES];
  string partial_message;

  void process_message(string message);
  MessageHandlerPointer message_handlers[NUM_TYPES];

  public:
    ConnectionManager(string hostname, string port);
    ~ConnectionManager();

    int connect();
    void disconnect();
    void listen();
};
/////////////////////////////////////////////////////////////////////////
//ConnectionManager.cpp
ConnectionManager::ConnectionManager(string hostname, string port,
                    void (*message_handlers[NUM_TYPES])(string)):
  hostname(hostname), port(port),
  message_types { "i", "t", "c", "r", "I", "u" }
{
  for(int i = 0; i < NUM_TYPES; i++)
  {
    this->message_handlers[i] = message_handlers[i];
  }
}
/////////////////////////////////////////////////////////////////////////
//GuiManager.h
class GuiManager
{
  void info_handler(string msg);
  void time_handler(string msg);
  void command_handler(string msg);
  void reply_handler(string msg);
  void inside_handler(string msg);
  void update_handler(string msg);

  public:
    GuiManager();
    ~GuiManager();

    MessageHandlerPointer message_handlers[NUM_TYPES];
};
/////////////////////////////////////////////////////////////////////////
//GuiManager.cpp
GuiManager::GuiManager()
{
  message_handlers[info_code]    = &info_handler;
  message_handlers[time_code]    = &time_handler;
  message_handlers[command_code] = &command_handler;
  message_handlers[reply_code]   = &reply_handler;
  message_handlers[inside_code]  = &inside_handler;
  message_handlers[update_code]  = &update_handler;
}
/////////////////////////////////////////////////////////////////////////
//generic main.cpp
int main()
{
    GuiManager gm();
    ConnectionManager cm("host", "45123", gm.message_handlers);
}

但是C ++不想让我那样做,我隐约明白为什么.成员函数不是自由函数.但是我希望我可以使这些函数在某种程度上与所有者或类无关.

But C++ doesn't want me to do that, and I vaguely understand why. Member functions aren't free functions. But I was hoping that I could perhaps make the functions somewhat owner- or class-agnostic?

无论哪种方式,我的想法都不会使我成为想要成为的人,所以我很高兴听到别人对最佳解决方案的印象.

Either way, my idea isn't going to get me where I want to be, so I'd be glad to hear someone else's impression of what the best solution would be.

此外,我认识到出于模块化的目的,我不让类直接相互连接可能会有点荒谬.我是否错过了原则/牺牲了原则的简单性?

Also, I recognize that I might be getting a little ridiculous for the sake of modularity in not letting the classes interface with one another directly. Am I missing the point / sacrificing simplicity for principle?

我对OO很陌生,所以我对任何答案的所有细节都感兴趣.=)

I'm fairly new to OO, so I'm interested in all of the details of any answer. =)

推荐答案

因此,如果我理解正确,则希望ConnectionManager将消息转发到GUIManager,而不必仅使用前向声明就包括GUIManager的标头.

So if I have got this right, you want your ConnectionManager to forward messages to your GUIManager, but without having to include the header of GUIManager, just using forward declarations.

当您注意到

void GUIManager::handle_info( std::string ) 

与指向自由函数的指针的类型不同

which is different from the type of a pointer to a free function

void handle_info (std::string).

要声明指向前者的指针,您必须编写

To declare a pointer to the former you have to write

typedef void (GUIManager::*MessageHandlerPointer)(string );

我写了一个简化的示例(使用Foo和Bar :)),其中Bar的实例将消息转发到Foo的实例.在这里:

I wrote a simplified example (with Foo and Bar :) ), where an instance of Bar forwards a message to an instance of Foo. Here it is:

#include <iostream>
#include <string>

using namespace std;

class Foo;
typedef void (Foo::*FooMessageHandlerPointer)(string );     // this is the type of a pointer to a member of Foo that gets a string and returns void.

class Bar
{
public:
    Bar ( Foo* foo_, FooMessageHandlerPointer ptr )
    :
    foo (foo_),
    p (ptr)
    {}

public:

    void ForwardMessage ( string s )
    {
        (foo->*p)(s);
    }

private:

    Foo* foo;
    FooMessageHandlerPointer p;
};


class Foo
{
public:

    void ProcessMessage (string s)
    {
        cout << "Foo received: " << s << "\n";
    }
};


int main (void)
{
    Foo foo1;

    Bar bar1 ( &foo1, &Foo::ProcessMessage );

    bar1.ForwardMessage( "Hello world!" );

    return 0;
}

请注意,在定义Bar时,它仅具有Foo的前向声明和成员函数指针的类型.还要注意,Bar不仅需要指向函数的指针,而且还需要指向实例的指针.当然,当您在主体中创建Bar的实例时,您需要有权访问标题.

Note that when Bar is defined, it has available only a forward declaration of Foo and the type of the member function pointer. Note also, that Bar needs not only a pointer to a function but also a pointer to the instance too. Of course when you create the instance of Bar in the main, you need to have access to the headers.

我希望我能正确回答您的问题,这对您有所帮助.否则,这是一个很好的练习,因为最近我一直在使用指向成员函数的指针:)

I hope i got your question right and this helps you. Otherwise it has been a good exercise since I 've been playing with pointers to member functions these days :)

更新:发表评论后,我认为您可能正在寻找类似委托的内容,该东西封装了要调用的函数,无论它是免费的还是成员函数.也许线程会有所帮助

UPDATE: After your comment, I think you may be looking for something like a delegate, something that encapsulates a function to call, whether it is free or member function. Maybe this thread will be helpful

这篇关于在类之间共享成员函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆