Прототип в переполнении стека

Будет ли ответ просто 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);

2

Решение

Все они Можно Работа:

  • А. если 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.

Что ты должен смотреть на:

  • разработка четких, выразительных, эффективных интерфейсов, которые легко использовать правильно (ни один из вышеперечисленных не подходит для этого, IMO)
  • правильное использование исключений вместо кодов возврата (если ошибка действительно исключительная)
  • прохождение этого string filename по ссылке
  • получить лучшего учителя.
4

Другие решения

Посмотрим:

  • не дает логического указания на успех. Ложь.
  • В проходит Movie по значению, поэтому нет никакого способа, которым он будет возвращен. Ложь.
  • С возвращает фильм, а bool передается по ссылке, поэтому он будет изменен. Правда.
  • (пропускать)
  • Е противоположность С, так что это тоже будет работать. Правда.
  • (вернуться к) D такой же как Е, кроме того, это будет const Movie это может или не может быть уместным. Правда?
  • F противоположность В, и терпит неудачу по той же причине. Ложь.

Это не очень понятный вопрос, и я хотел бы указать свои аргументы в пользу ответов на тест / домашнее задание.

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 ("успешно") выполнен успешно.
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") не удалось.
1
По вопросам рекламы [email protected]