Избегать пока (! Is_eof) - PullRequest
       23

Избегать пока (! Is_eof)

1 голос
/ 07 февраля 2012

Я работаю с библиотекой (C ++), где объект должен быть инициализирован потоком.В примере кода, поставляемом с библиотекой, используется этот код:

// Declare the input stream
HfstInputStream *in = NULL;

try 
{
    // This sets up the special stream object for the later object (see below)
    in = new HfstInputStream("pathToFile.hfsto");
} 
// catch errors...
// {omitted}

// Initialize the object
while (not in->is_eof()) {
    if (in->is_bad()) 
    {
        std::cerr << "ERROR: Stream cannot be read." << std::endl;
        exit(1); 
    }
    // Here we initialize the object using the stream
    HfstTransducer t(*in);
}

Моя проблема заключается в том, что этот объект нельзя использовать вне цикла while из-за области видимости.и я должен объявить это с помощью потока (насколько я могу судить), поэтому я не могу объявить и инициализировать его с помощью потока внутри цикла.

Мои вопросы (1) я не прав?Могу ли я как-то объявить это вне цикла?(2) есть ли другой (лучший) способ сделать это, чтобы избежать цикла вообще.Например, если бы я использовал try / catch и перехватил исключения.

Я очень новичок в C ++ и ищу полезные практики, поэтому, пожалуйста, дайте мне знать, что к чему.Спасибо.

Также, чтобы было ясно, я хочу создать класс, который бы использовал постоянную версию этого объекта, поэтому мне не нужно постоянно создавать / уничтожать эти объекты каждый раз, когда мне нужно использоватьих.

PS: вот ссылка на документацию для объекта, если он имеет отношение

РЕДАКТИРОВАТЬ: Если я пытаюсь объявить переменную вне цикла, а затем инициализироватья получаю сообщение об ошибке

HfstTransducer t;
while (not in->is_eof()) {
    t(*in);
}
// ERROR: main.cpp:47:0 main.cpp:47: error: no match for call to '(hfst::HfstTransducer) (hfst::HfstInputStream&)'

Я пытаюсь инициализировать его неправильно?

1 Ответ

2 голосов
/ 07 февраля 2012

Чтобы достичь того, что вам нужно, у вас должен быть указатель на объект, объявленный за пределами области действия while:

//Declare the pointer to the object outside the while score. This way it will be available to you even outside of the while
HfstTransducer* t = 0;
// Initialize the object
while (not in->is_eof()) {
    if (in->is_bad()) 
    {
        std::cerr << "ERROR: Stream cannot be read." << std::endl;
        exit(1); 
    }
    // Here we initialize the object using the stream only if it's not already been initialized before
    // thanks to Necrolis for the observation
    if(t == 0)
        t = new HfstTransducer(*in);
}

Это объявит и инициализирует объект типа HfstTransducer вкуча.Это означает, что деструктор не будет вызван сам по себе после того, как вы покинете область действия, но вы должны явно вызвать его, вызвав:

delete t;

РЕДАКТИРОВАТЬ: Чтобы ответить на ваш общий вопрос о указателе против обычного объекта:

Это очень важная часть C / C ++.Статью, чтобы лучше объяснить это, можно увидеть здесь .

Если бы я объяснил это в нескольких словах, сделав:

HfstTransducer t;

Вы объявляете объекттакого типа и положить его в стек.Его срок службы длится ТОЛЬКО до конца объема.Вы не можете получить к нему доступ вне области видимости, так как его деструктор будет вызван, как только область действия закончится.

С другой стороны,

HfstTransducer*t = new HfstTransducer();

инициализирует t как объект HfstTransducer.введите и поместите его в кучу.Что касается кучи, обратитесь к статье выше, но это в основном память, выделенная вашей программе операционной системой.В C ++ вы запрашиваете память в куче с операторами new и освобождаете ее с помощью оператора delete .В C вы достигаете того же с помощью функций free () и malloc () .

Таким образом, что-то в куче живо на протяжении всей программы, если толькоВы явно называете его деструктором.Как вы можете сделать в этом примере, вызвав delete t;

Невыполнение этого требования приводит к тому, с чем сталкиваются все программисты C / C ++, к так называемым утечкам памяти.В основном это память, которую вы считаете свободной, но не потому, что вы забыли удалить / освободить ее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...