0

具体例: 制御ユニットの抽象化。これは、ソケットによって表されるリモート ユニットでもあります。使いやすくするために、ソケットを作成し、コンストラクターで既に accept() することを検討します。

しかし、これは少し奇妙に感じます。そのようなコンストラクターは常に失敗する可能性があります。そしてそれはブロックする可能性があります。私を不快にさせない方法はありますか、それとも単に OO であり、その薬を服用しなければならないのでしょうか?

(この質問は、特に流行の OO 言語とそこで使用される一般的に受け入れられているスタイルに関連しています)

4

4 に答える 4

5

コンストラクターをロックすることは必ずしも悪いことではありませんが、ユーザーからそれを隠すことを検討します。何かのようなもの:

connection establish_connection();

ユーザーコードから、次のように表示されます。

connection c = establish_connection();

接続が確立され、アクティブな接続が返されることは理にかなっているようです。socketユーザーは、コードが失敗(例外)またはブロックされる可能性があることを期待しているため、多くのライブラリでaの作成が非ブロック呼び出しであることを考えると、そこに驚くことはありません。

注:このコード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

AbstractFactoryのデザインパターンを見てください。通常の方法でインスタンスを作成することを避けて、独自のインターフェースから継承する具象クラスを非表示にすることができます。次に、具象クラスにアクセスできるクラスを作成し、ファクトリのようにこれらのオブジェクトを作成できます。例えば:

あなたの図書館で:

//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 に答える