问题描述
我正在设计一个应用程序,该应用程序使用一个类来管理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
这篇关于在类之间共享成员函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!