0

ifstreamC ++では、オブジェクトをオブジェクトのようなテスト式として使用できますか?そうでない場合、なぜですか?

例えば

ifstream ifs ("myfile.txt");
while( ifs ){
   //read and process data..
}

クラスがありますが、コンパイラがオブジェクトをテスト式として渡すことができるようにするには、どの演算子をオーバーロードする必要がありますか?

例えば

MyClass obj1;
if( obj1 ){
   //do something..
}

while( obj1 ){
   //do something repeatedly..
}

どちらも有効な式である必要があります。

4

6 に答える 6

3

クラスにオーバーロードを実装する必要がありboolます。このようなもの:

class myClass {
    public:
        explicit operator bool() const { return condition; }
};

ifwhileステートメントの両方で機能します。ただし、コンパイラがC ++ 11をサポートしていない場合、explicitこのオーバーロードでキーワードを使用することはできません。

于 2013-02-19T15:12:52.630 に答える
1

あなたが持っているいくつかのオプションがあります。おそらく最良の方法は、をオーバーロードすることoperator bool()です。そのようです:

class A{
 public:
   operator bool()
   {
     return flag;
   }

 private:
   bool flag;
};

編集:コメントで指摘されているように、使用する場合は、キーワードを先頭にC++11追加して演算子を明示的にすることをお勧めします。explicitそれ以外の場合は、おそらく使用する方が良いですoperator void*()

于 2013-02-19T15:12:38.470 に答える
1

いくつかのオプションがあります。

operator boolクラスにオーバーロードを実装する必要はありません。

そして、それは一般的に最良の選択ではありません。


最良:名前付き状態チェック。

名前付き状態チェックメソッドを使用するのが最善です。たとえば、iostreamにはfailメンバーが含まれているため、次のように記述できます。

while( !cin.fail() ) { ... }

自分のクラスの場合、次のようになります。

struct S
{
    bool is_good() const { return ...; }  // Whatever name.
};


So-so:へのexplicit変換bool

次善の策はexplicit変換演算子です。これを使用explicitすると、オブジェクトの1つを関数の引数として渡すために誤って呼び出されるのを防ぐことができます。explicit変換演算子は引き続き条件で使用されるため、次のように記述できます。

while( cin ) { ... }

これはC++11では

explicit operator bool () const { return !fail(); }

あなた自身のクラスの場合、それは次のようになります

struct S
{
    explicit operator bool () const { return ...; }
};


良くない:「プライベート」ポインタ型への暗黙の変換。

第3に、変換をサポートしないコンパイラーexplicit、つまりC ++ 03コンパイラーを使用していて、説明できない理由で最良の選択である名前付きチェックを望まない場合は、次のような結果タイプを選択できます。不注意による呼び出しの可能性を最小限に抑えます。

void*C ++ 03では、iostreamsは(toではなく)toへの暗黙的な変換を使用していましたbool

一部の人々は、結果がC ++ 03では、クライアントコードにアクセスできない型へのポインタとなる「安全なブールイディオム」を使用することを提唱しています。


絶対に最悪:暗黙の変換bool

すべての中で最悪のオプションは次のようなものです

struct S
{
    operator bool () { return ... }
};

これとともに

  • コードを呼び出すことから、どの条件がチェックされているかを知ることはできません。

  • S演算子は、関数の引数として渡すために誤って呼び出される可能性があります。

  • オブジェクトに対して変換を呼び出すことはできませんconst

のみを追加するconstと、少し悪くなります。

それはまだ非常に悪いです。:-)

于 2013-02-19T15:27:55.260 に答える
0

operator bool()この動作を提供するには、オーバーロードする必要があります。ただし、これは、変換に意味のある意味がある場合にのみ行ってください。これは、クラスのすべてのユーザーが明白で期待していることです。

于 2013-02-19T15:14:31.987 に答える
0

コンパイラは式をboolに暗黙的にキャストしようとするため、次のように型キャスト演算子をクラスに追加する必要があります。

class SomeClass {
    operator bool() {
        return true; // a boolean expression should go here.
    }
}

これにより、クラスをブール型にキャストできるため、ifwhileなどで使用できるようになります。ただし、これにより、型からブールへの暗黙的な変換が可能になり、次のことを確認することが重要です。これは理にかなっています。

多くの場合、次のような動作の方法を提供する方が賢明です。

while (myObj.hasMoreElements())

また

if (someObj.isValid())

これにより、何がテストされているかがすぐにわかります。ただし、 boolへの変換が理にかなっている場合は、それを選択してください。

于 2013-02-19T15:17:38.630 に答える
0

型変換演算子はいくつでもオーバーロードできます。従来の方法はoperator void*()() const、falseの場合はnullポインターを返し、trueの場合は(従来は)非nullポインターを返すことでしthisた。C ++ 11では、オーバーロードすることもできますがexplicit operator bool() const、コンパイラでまだ許可されていない場合は、これはお勧めしませんexplicitboolが整数型であり、がないとexplicit他の整数型に変換されるという事実は、驚くべき過負荷の解決につながる可能性があります。

これを行う場合は、もオーバーロードする必要があります。これによりoperator!() const、それif ( ! myObj )も明確に定義されます。

そして最後に、これを実行するかどうかを実際に検討する必要があります。ostreamクラスは標準の一部であり、誰もがそれらを見て、使用し、知っているので、それを回避しwhile ( someStream >> object )ます。イディオムはどこにでもあります。しかし、全体として、それは誤解を招き、2つ以上の可能な状態を持つクラスに対する演算子のオーバーロードの乱用です。isValidまたはまたはその他のisReady関数がより適切です。

于 2013-02-19T15:20:53.963 に答える