0

具体示例:控制单元的抽象,它也可以是由套接字表示的远程单元。为了便于使用,我考虑在构造函数中创建套接字并接受()。

不过,这感觉有点奇怪。这样的构造函数总是会失败。它可能会阻塞。有没有一种方法不会让我感到不舒服,或者只是 OO 并且我必须服用那种药丸?

(这个问题尤其与流行的 OO 语言和那里使用的普遍接受的风格有关)

4

4 回答 4

5

虽然锁定构造函数不一定是坏事,但我会考虑对用户隐藏它。就像是:

connection establish_connection();

从用户代码中,如果他们看到:

connection c = establish_connection();

建立连接并返回活动连接似乎是明智的。用户期望代码可能会失败(异常)或阻塞,因此不会有任何意外,因为在许多库中创建 asocket是非阻塞调用。

注意:在这段代码中connection代表一个活动连接,库应该控制是否connection可以直接创建,是否可以关闭(通过析构函数以外的任何东西,即connection对象是否可以活动而不代表活动连接)以及它是否可以复制以及语义是什么。

于 2012-07-27T15:54:21.503 回答
4

在 C++ 中,类模板std::lock_guard将愉快地阻塞,直到它获得一个互斥锁:

std::mutex m;

{
    std::lock_guard<std::mutex> _(m);

    //...
}

这是完全合法的使用,并且是使用 SBRM 成语(“范围绑定资源管理”,以前称为“RAII”)的强烈惯用 C++。

于 2012-07-27T15:28:06.513 回答
2

是的,构造函数可以阻塞。经典示例是表示 RAII 互斥锁的类,在构造时获取互斥锁。该构造函数将阻塞,直到另一个线程释放互斥锁。

如果您完全accept 失败,那么您应该从构造函数中抛出异常以指示此类失败。

于 2012-07-27T15:27:47.077 回答
0

看看抽象工厂设计模式。您可以隐藏从它们自己的接口继承的具体类,避免您以正常方式创建实例。然后,您创建一个可以访问具体类并可以为您构建这些对象的类,例如工厂。例如:

在您的图书馆中:

//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#。但是您可以使用名称空间或标头包含(不包括)来隐藏具体类。您现在被迫“要求”您的工厂类为您创建该对象。

于 2012-08-10T18:30:04.573 回答