Будет ли ответ просто C и E? Я запутался, как будто бул &статус можно передать по ссылке?
Вам нужна функция, которая считывает данные о фильме из указанного файла и возвращает объект 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);
Все они Можно Работа:
А. если Movie
сам может иметь общеизвестная плохая ценность (эквивалентно end
, EOF
или же NULL
), или член, чтобы проверить, находится ли он в хорошем состоянии, это нормально:
Movie readMovie(string filename);
Movie m = readMovie(filename);
if (m.good() || m != Movie::InvalidMovie || ... ) {
однако я подозреваю, что спрашивающий думает это не считается указывает на успех через возвращаемое значение …
Б. если Movie
typedef’d для указателя, или shared_ptr
или, если Movie — легкая обертка для пересчитанного MovieImpl
объект (например), это нормально (потому что общее состояние вызывающего абонента изменяется с помощью readMovie
«s копия из обертки)
bool readMovie(string filename, Movie m);
однако я подозреваю, что спрашивающий думает это не считается указывает на успех через … параметр. (Примечание. Movie
также может быть typedef, умный указатель или другая вещь стиля дескриптора тела).
C. это определенно хорошо (и даже спрашивающий знает это)
Movie readMovie(string filename, bool &status);
D. те же ограничения, что и B
bool readMovie(string filename, const Movie &m);
Е. хорошо
bool readMovie(string filename, Movie &m);
Ф. тупой: это Можно работа в том же режиме была, что и у А, но статусный параметр бесполезен и вводит в заблуждение. Итак, я уверен, что спрашивающий не ожидает, что это сработает:
Movie readMovie(string filename, bool status);
Итак, что действительно можно сделать, чтобы работать: все из них.
Что спрашивающий, вероятно, хочет услышать: C, E.
Что ты должен смотреть на:
string filename
по ссылкеПосмотрим:
Movie
по значению, поэтому нет никакого способа, которым он будет возвращен. Ложь.bool
передается по ссылке, поэтому он будет изменен. Правда.const Movie
это может или не может быть уместным. Правда?Это не очень понятный вопрос, и я хотел бы указать свои аргументы в пользу ответов на тест / домашнее задание.
Фильм это большая вещь, поэтому он должен быть распределен динамически.
Поэтому используйте умный указатель.
Приведенный ниже код демонстрирует / доказывает, как каждая подпись предлагаемой функции поддерживает возврат загруженного фильма и проверку его успешности или неудачи. с наиболее естественным толкованием предоставленной информации (в частности, что «фильм» — это фильм).
Обратите внимание, что подписи в вопросе являются примерами 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 ("успешно") выполнен успешно. a :: readMovie ("fail") не удалось. b :: readMovie ("успешно") выполнен успешно. b :: readMovie ("fail") не удалось. c :: readMovie ("успешно") выполнен успешно. c :: readMovie ("fail") не удалось. d :: readMovie ("успешно") выполнен успешно. d :: readMovie ("fail") не удалось. e :: readMovie ("успешно") завершился успешно. e :: readMovie ("fail") не удалось. f :: readMovie ("успешно") завершился успешно. f :: readMovie ("fail") не удалось. right :: readMovie (L "успешно") успешно выполнено. right :: readMovie (L "fail") не удалось.