2

答えはCとEだけでしょうか?bool &status を参照渡しできるかどうかについて混乱していますか?

指定したファイルから映画に関するデータを読み取り、戻り値またはパラメーターを介して Movie オブジェクトを返す関数が必要です。また、戻り値またはパラメーターを介して、成功または失敗の何らかの指示を返す必要があります。上記の要件のプロトタイプとして選択できるのは、次のうちどれですか? 該当するものをすべて選択。

A.  Movie readMovie(string filename);
B.  bool readMovie(string filename, Movie m);
C.  Movie readMovie(string filename, bool &status);
D.  bool readMovie(string filename, const Movie &m);
E.  bool readMovie(string filename, Movie &m);
F.  Movie readMovie(string filename, bool status);
4

3 に答える 3

4

それらすべて機能します:

  • A. それMovie自体がよく知られている悪い値end( 、EOFまたはと同等NULL)、または状態が良好かどうかを確認するメンバーを持つことができる場合、これは問題ありません。

    Movie readMovie(string filename);
    Movie m = readMovie(filename);
    if (m.good() || m != Movie::InvalidMovie || ... ) {
    

    ただし、質問者は、これは戻り値を介して成功を示しているとは見なされないと考えているのではないかと思います...

  • B.Movieがポインタまたは に typedef されているshared_ptr場合、または Movie が refcountedMovieImplオブジェクトの軽量ラッパーである場合 (たとえば)、これは問題ありません (呼び出し元の共有状態がのラッパーreadMovieコピーを介して変更されるため)

    bool readMovie(string filename, Movie m);
    

    ただし、質問者は、これは... パラメータを介した成功を示すものとしてカウントされないと考えているのではないかと思います。(注: Aは、typedef、スマート ポインター、またはその他のハンドル本体スタイルのものでもかまいません)。Movie

  • C. これは間違いなく問題ありません (質問者もそれを知っています)

    Movie readMovie(string filename, bool &status);
    
  • D. B と同じ制約

    bool readMovie(string filename, const Movie &m);
    
  • E.罰金

    bool readMovie(string filename, Movie &m);
    
  • F. 愚か: これA と同じように機能しますが、ステータス パラメータは役に立たず、誤解を招きます。したがって、質問者はこれが機能することを期待していないと確信しています。

    Movie readMovie(string filename, bool status);
    

つまり、実際に機能させることができるのは、それらすべてです。

質問者がおそらく聞きたいこと: C、E.

あなたが見るべきもの:

  • 正しく使いやすい、明確で表現力豊かで効率的なインターフェイスを設計する (上記のどれにも当てはまらない、IMO)
  • 戻りコードの代わりに例外を適切に使用する (失敗が本当に例外的な場合)
  • string filenameそれを const 参照で渡す
  • より良い教師を得る。
于 2012-12-09T20:31:44.413 に答える
1

どれどれ:

  • Aは、成功のブール値を示しません。間違い。
  • Bは値渡しMovieなので、返されることはありません。間違い。
  • Cはムービーを返しますbool。これは ref によって渡されるため、変更されます。真実。
  • (スキップ)
  • ECの反対なので、これも機能します。真実。
  • (戻る) DはEと同じですが、const Moviethis が適切である場合とそうでない場合があります。 真実?
  • FBの反対であり、同じ理由で失敗します。間違い。

それは非常に明確な質問ではありません。テスト/宿題での回答の理由を示します。

于 2012-12-09T18:54:05.357 に答える
1

映画は大きなものなので、動的に割り当てる必要があります。

したがって、スマート ポインターを使用します。

以下のコードは、提供された情報の最も自然な解釈(特に、「映画」は映画である) を使用して、提案されたすべての関数シグネチャが、ロードされた映画を返し、それが成功したか失敗したかを確認する方法を示しています。

質問の署名はすべて、Very Bad Design™ の例であることに注意してください。

rightただし、以下のコードの名前空間に示されている署名は問題ありません。

  • 一般に、Windows ファイル名をサポートします。

  • ロードが失敗した場合、呼び出し元のコードに (誤って) 再生するムービー オブジェクトがないことが保証されます。これは、失敗を示す例外をスローすることによって行われます。

  • への参照によって文字列を渡しますconst(効率のため、および一般的な良い習慣として)。

#include <memory>           // std::shared_ptr
#include <new>              // std::nothrow
#include <stdexcept>        // std::runtime_error
#include <string>           // std::string

class MovieData
{
    // Whatever
};

//          *** A movie is a big thing, so it should be allocated dynamically. ***
//          *** Therefore, use a smart pointer. ***
//
typedef std::shared_ptr< MovieData > Movie;

namespace a {
    using std::string;
    using std::nothrow;

    Movie readMovie(string filename)
    {
        return 0?0
            : filename == "succeed"?    Movie( ::new(nothrow) MovieData )
            : Movie();
    }

    bool test( string const& filepath )
    {
        Movie const m = readMovie( filepath );
        return (m != nullptr);
    }
}

namespace b {
    using std::string;
    using std::nothrow;

    bool readMovie(string filename, Movie m)
    {
        if( filename != "succeed" || m == nullptr )
        {
             return false;
        }
        *m = MovieData();
        return true;
    }

    bool test( string const& filepath )
    {
        Movie const m( ::new(nothrow) MovieData );
        return readMovie( filepath, m );
    }
}

namespace c {
    using std::string;
    using std::nothrow;

    Movie readMovie(string filename, bool &status)
    {
        status = false;
        if( filename != "succeed" )
        {
            return Movie();
        }
        Movie const result( ::new(nothrow) MovieData );
        status = true;
        return result;
    }

    bool test( string const& filepath )
    {
        bool result = false;
        readMovie( filepath, result );
        return result;
    }
}

namespace d {
    using std::string;
    using std::nothrow;

    bool readMovie(string filename, const Movie &m)
    {
        if( filename != "succeed" || m == nullptr )
        {
            return false;
        }
        *m = MovieData();
        return true;
    }

    bool test( string const& filepath )
    {
        Movie const m( ::new(nothrow) MovieData );
        return readMovie( filepath, m );
    }
}

namespace e {
    using std::string;
    using std::nothrow;

    bool readMovie(string filename, Movie &m)
    {
        if( filename != "succeed" )
        {
            return false;
        }
        m.reset( ::new(nothrow) MovieData );
        return (m != nullptr);
    }

    bool test( string const& filepath )
    {
        Movie m;
        return readMovie( filepath, m );
    }
}

namespace f {
    using std::string;
    using std::nothrow;

    Movie readMovie(string filename, bool status)
    {
        (void) status;  struct status;      // Intentionally not used.
        if( filename != "succeed" )
        {
            return Movie();
        }
        return Movie( ::new(nothrow) MovieData );
    }

    bool test( string const& filepath )
    {
        return (readMovie( filepath, bool() ) != nullptr);
    }
}

namespace right {
    using std::wstring;         // Using wide string supports nearly all Windows filenames.
    using std::runtime_error;

    Movie readMovie( wstring const& filepath )
    {
        if( filepath != L"succeed" )
        {
            throw std::runtime_error( "right::readMovie: failed because ..." );
        }
        return Movie( new MovieData );
    }

    bool test( wstring const& filepath )
    {
        try
        {
            readMovie( filepath );
            return true;
        }
        catch( ... )
        {
            return false;
        }
    }
}

#define TEST( name, filename ) \
    wcout << #name "::readMovie" << "( " << #filename << " ) " \
    << (name ::test( filename )? "succeeded" : "failed") << "." << endl;

#include <iostream>     // std::wcout, std::endl

int main()
{
    using std::wcout;  using std::endl;  using std::boolalpha;

    wcout << boolalpha;
    TEST( a, "succeed" );
    TEST( a, "fail" );
    wcout << endl;
    TEST( b, "succeed" );
    TEST( b, "fail" );
    wcout << endl;
    TEST( c, "succeed" );
    TEST( c, "fail" );
    wcout << endl;
    TEST( d, "succeed" );
    TEST( d, "fail" );
    wcout << endl;
    TEST( e, "succeed" );
    TEST( e, "fail" );
    wcout << endl;
    TEST( f, "succeed" );
    TEST( f, "fail" );
    wcout << endl;
    TEST( right, L"succeed" );
    TEST( right, L"fail" );
}

出力 (テスト結果):

a::readMovie( "succeed" ) が成功しました。
a::readMovie( "fail" ) が失敗しました。

b::readMovie( "succeed" ) が成功しました。
b::readMovie( "fail" ) が失敗しました。

c::readMovie( "succeed" ) が成功しました。
c::readMovie( "fail" ) が失敗しました。

d::readMovie( "succeed" ) が成功しました。
d::readMovie( "fail" ) が失敗しました。

e::readMovie( "succeed" ) が成功しました。
e::readMovie( "fail" ) が失敗しました。

f::readMovie( "succeed" ) が成功しました。
f::readMovie( "fail" ) が失敗しました。

right::readMovie( L"succeed" ) が成功しました。
right::readMovie( L"fail" ) が失敗しました。
于 2012-12-09T20:58:12.937 に答える