具体示例:控制单元的抽象,也可以是由套接字表示的远程单元。为了便于使用,我考虑在构造函数中创建套接字和accept()。
然而,这感觉有点奇怪。这样的构造函数总是会失败。它可以阻止。有没有一种方法不会让我感到不舒服,或者它只是OO而我必须服用那种药?
(这个问题特别涉及时尚的OO语言和那里普遍接受的风格)
答案 0 :(得分:5)
虽然锁定构造函数并不一定是坏事,但我会考虑将其隐藏在用户之外。类似的东西:
connection establish_connection();
从用户代码中,如果他们看到:
connection c = establish_connection();
建立连接并返回活动连接似乎是明智的。用户期望代码可能失败(异常)或阻塞,因此在那里不会出现意外,考虑到在许多库中创建socket
是非阻塞调用。
注意:在此代码connection
代表一个活动连接,库应该控制connection
是否可以直接创建,是否可以关闭(除了析构函数之外的任何东西,即connection
对象是否可以存活而不代表活动连接)以及是否可以复制它以及语义是什么。
答案 1 :(得分:4)
在C ++中,类模板std::lock_guard
将很快阻塞,直到它获得对互斥锁的锁定:
std::mutex m;
{
std::lock_guard<std::mutex> _(m);
//...
}
这是一个完全合法的用法,并且使用SBRM习惯用法(“范围限制资源管理”,以前称为“RAII”)使用强烈惯用的C ++。
答案 2 :(得分:2)
是的,构造函数可以阻止。典型的例子是代表RAII互斥体的类,在构造时获取互斥体。该构造函数将阻塞,直到另一个线程释放互斥锁。
如果您的accept
失败,那么您应该从构造函数中抛出异常以指示此类失败。
答案 3 :(得分:0)
看一下Abstract Factory设计模式。您可以隐藏从其自己的接口继承的具体类,从而避免以正常方式创建实例。然后,您创建一个可以访问具体类的类,并可以为您构建这些对象,就像工厂一样。例如:
在你的图书馆:
//ConcreteWindow class must not be visible to the final user.
class ConcreteWindow : public AbstractWindow
{
...
};
class GUIManager
{
public:
AbstractWindow* createWindow()
{
return new ConcreteWindow();
}
...
};
在您的申请中:
GUIManager* gui = new GUIManager();
//ConcreteWindow class not visible.
AbstractWindow* myWindow = gui->createWindow();
在C ++中,你没有类的访问修饰符,比如Java和C#。但是您可以使用名称空间或标题包含(不包括)来隐藏具体类。你现在被迫&#34;问&#34;您的工厂类为您创建该对象。