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,EOFNULL),或者一个成员来检查它是否处于良好状态,这很好:

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

    但是,我怀疑提问者认为这不能算作通过返回值表示成功......

  • B. 如果Movie是 typedef'd 到一个指针,或者 a shared_ptr,或者如果 Movie 是一个引用计数MovieImpl对象的轻量级包装器(例如),这很好(因为调用者的共享状态是通过包装器readMovie副本改变的)

    bool readMovie(string filename, Movie m);
    

    但是,我怀疑提问者认为这不能算作通过 ... 参数表示成功。(注意。AMovie也可以是 typedef、智能指针或其他句柄体样式的东西)。

  • 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

电影是一件大事,所以应该动态分配。

因此,使用智能指针。

下面的代码演示/证明了每个提议的函数签名如何支持返回加载的电影并检查它是成功还是失败,并以最自然的方式解释所提供的信息(特别是“电影”是电影)。

请注意,问题中的签名都是非常糟糕的设计™的示例。

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" ) 成功。
对::readMovie(L"fail") 失败。
于 2012-12-09T20:58:12.937 回答
1

让我们来看看:

  • A不提供成功的布尔值指示。错误的。
  • B是按值传递Movie的,所以它不可能被返回。错误的。
  • C返回一个电影,并且bool由 ref 传递,因此它将被修改。真的。
  • (跳过)
  • EC相反,所以它也可以工作。真的。
  • (返回)DE相同,除了它const Movie可能是或可能不合适的。 真的?
  • F与B相反,并且由于相同的原因而失败。错误的。

这不是一个非常清楚的问题,我会指出我对测试/作业答案的推理。

于 2012-12-09T18:54:05.357 回答