C++在其他类中使用(通信)对象

C++ Using (communications) object in every other class

本文关键字:通信 对象 其他 C++      更新时间:2023-10-16

我最近创建了一个"communications"对象/抽象类,可以在上面使用以下函数:"发送"、"接收"、"调试发送"等

现在,我想在其他类中使用这个对象,这样我就可以用它来发送调试消息。

现在我必须做:

#include "../communication/ICommunication.hpp"
extern Communication* comm;

在我想要使用此对象的任何其他文件/类中。虽然这看起来效果很好,但我想知道是否有更整洁的方法可以做到这一点。

我相信这是有软件模式的,尽管我记不起名字,也记不起实现。我相信,图案的名字是一个人的姓氏。

我想知道这个模式的名称(或者任何适合这个目的的模式),所以我可以自己尝试实现。如果可能的话,还有一些关于为什么该模式比"include-and-extern"代码更好的论点。

我想知道这个模式(或任何适合这个目的的模式)的名称,所以我可以自己尝试实现。如果可能的话,还有一些关于为什么该模式比"include-and-extern"代码更好的论点。

目前使用的最佳实践是接口抽象和依赖项注入:

首先抽象你将要在你的通信对象上使用的操作:

struct Communicator
{
virtual void send(const std::string&) = 0;
virtual std::string receive() = 0;
// etc
};
// injectable Communicator implementation that does nothing; this is useful as
// a default argument for code that uses communicators: it will show the dependency 
// explicitly, but setting it as a default argument ensures that client code
// doesn't _have to_ use a communicator, if you don't have one available
struct NoOpCommunicator: Communicator
{
void send(const std::string&) override {}
std::string receive() override { return {}; }
} dummy_communicator; // <--- notice this global

客户代码:

class YourClientCode // (uses a Communicator)
{
public:
YourClientCode(Communicator& c = dummy_communicator) // communicator instance,
// dependency injected here
: com(c)
{   
}
private:
void f() { com.send("f()"); /* ... */ }
Communicator& com;
};
auto client1 = YourClientCode{};
auto client2 = YourClientCode{ GetActualCommunicatorReference() };

这比include+extern要好,因为它不会硬编码对通信器的依赖,也不会强制要求使用客户端代码,您必须启动并运行通信器。这大大提高了代码的可测试性和可重用性。

您所了解的这个模式被称为singleton(通常被称为反模式)。它应该如下所示:

struct MySingleton {
static MySingleton& getInstance() {
static MySingleton singleton;
return singleton;
}
};

更好的方法是将Communication实例作为构造函数的参数传递给每个类。您也可以将它封装到shared_ptr中,这样一旦所有类都不再引用它,就会自动调用Communication对象的析构函数。

如果可能的话,还可以讨论为什么该模式比"include and extern"代码更好。

我认为您可能会遇到的一个问题是如何管理通信对象的生存期。它应该在第一次使用之前创建,我想它应该在任何其他类或函数想要使用它之后被销毁

我不确定singleton是否适合Communication对象,我假设您使用它与服务器建立连接,过一段时间后断开连接。Sigleton可以做到这一点,但根据我的经验,Singleton更多地用于寿命更长的对象,比如整个应用程序的持续时间。