2016-12-22 5 views
4

簡体スニップ:この作品インスタンス化せずにコンストラクタの呼び出しを防止できますか?私のクラスの

class UpdatingSystem 
/* when system is "unsafe" it marks this condition by instantiating an 
UpdatingSystem item. While this item exists errors are handled in a 
particular way. When the UpdatingSystem item goes out of scope error 
handling reverts to normal.*/ 
{ 
private: 
static THREAD int updatingSystemCount_; 

public: 
UpdatingSystem(const char* caller){updatingSystemCount++}; 
~UpdatingSystem(){updatingSystemCount--}; 
}; 

{ 
    UpdatingSystem tempUnsafe("Reason it's unsafe"); 
    // do stuff that requires the system be 'unsafe' 
} // Revert to safe when destructor runs 

これにはない:

{ 
    UpdatingSystem("Reason it's unsafe"); 
    // do stuff that requires the system be 'unsafe' 
} 

...と呼ばれるコンストラクタは、一時的な項目と作成されますので、デストラクタはすぐに実行され、システムを「安全」な状態にしないでください。

2番目の欠陥のあるバージョンを書き込むのは間違いやすいです。 インスタンス化せずにそのようなコンストラクタの呼び出しを防ぐ方法はありますか?

+0

これを防ぐ手段はありません。 C++は匿名の一時ファイルを許可しますが、あなたはそれについて何もできません。 –

+1

いいえ、クラスは、オブジェクトが左辺値に保存されていることを知る方法がありません。 –

+0

私はそれを削除しました、ミスは質問を読んで:)その初期のコーヒーはまだ持っています:) – Rob

答えて

2

インスタンシエーションなしでこのようなコンストラクタの呼び出しを防止する方法はありますか?

いいえ、ユーザーがクラスをインスタンス化する方法を制御することはできません。あなたが明示的にあなたには、いくつかの策略を行うことができます一時を禁止したい場合は

class SystemUpdateGuard {..} 

{ 
    SystemUpdateGuard guard_system_update("Reason it's unsafe"); 
    // do stuff that requires the system be 'unsafe' 
} // Revert to safe when destructor runs 
1

おそらく、より良いは、のようなものを適切な使用を奨励するでしょう。

のコンストラクタをprivateにして、unique_ptr<UpdatingSystem>への参照のみを受け入れるファクトリクラスを作成します。この方法は、それは左辺値を必要とするため、スマートポインタの目的は、一度スコープ、何かlikeの外に破棄されます。これは、建築である

... 
UpdatingSystem(const char* caller, std::function<void()> func) 
{ 
    updatingSystemCount++; 
    f(); 
    updatingSystemCount--; 
}; 
... 

UpdatingSystem("whatever", [&](){ do_unsafe_stuff(); }); 
+0

また、 'unique_ptr'を生成する' UpdatingSystem'クラスの静的関数を使うこともできます。このように 'static unique_ptr UpdatingSystem :: Create()'です。ポインタを作成するためにまったく新しいクラスを作成しないようにします: –

+0

ありがとうGill、それは私が必要とするように見えます。 – user3775289

+0

私はあなたの提案も試してみます – user3775289

1

何このようなガードについて問題。

唯一の解決策は、安全でない機能を変更することです。 UpdatingSystemオブジェクトが必要です。

最後に、あなたのコードは次のようになります...

{ 
    UpdatingSystem tempUnsafe("Reason it's unsafe"); 
    unsafe_operation(tempUnsafe); 
    safe_operation(); 
    another_unsafe_operation(tempUnsafe, 42); 
} // Revert to safe when destructor runs 

これは不可能最初UpdatingSystemオブジェクトを作成せずに危険な操作を実行することによって、あなたの問題を解決します。

安全でない関数を更新するのは簡単ですが、参照に渡すだけです。あなたはオブジェクトで何かをしたり、それをコピーする必要はありません。

another_unsafe_operation(UpdatingSystem const & lock, int data) 
{ 
    // Do stuff, you don't even need to use the lock for anything. 
} 

このアプローチは、一般に、安全でない機能を正しく処理する唯一の方法であるため、プログラマーにとってもより使いやすくなります。

このように関数レベルで安全性を定義することが「不可能」である場合は、プログラムの抽象概念を再考する必要があります。

+0

私はこのアプローチが好きです。これは、基本的に、安全でないコードをラップすることによってOPが望むものを実現します。 –

0

#include <iostream> 
#include <memory> 

class UpdatingSystem 
{ 
    friend class UpdatingSystemFactory; 
    public: 
    ~UpdatingSystem() { std::cout << "destructor UpdatingSystem"; } 
    private: 
    UpdatingSystem() { std::cout << "constructor UpdatingSystem";} 
}; 

class UpdatingSystemFactory 
{ 
    public: 
    static void GenerateUpdatingSystem(std::unique_ptr<UpdatingSystem>& ptr) 
    { 
     ptr = std::unique_ptr<UpdatingSystem>(new UpdatingSystem()); 
    } 
}; 

int main() 
{ 
    //..when having to create an updating system: 
    { 
     std::unique_ptr<UpdatingSystem> tmp; 
     UpdatingSystemFactory::GenerateUpdatingSystem(tmp); 
    } 
    return 0; 
} 
関連する問題