Re: Какой прототип выбрать?
От: alexeiz  
Дата: 20.10.11 02:25
Оценка: +1
Здравствуйте, DirtyGarry, Вы писали:

DG>Есть блок данных. В этом блоке нужно найти данные и вернуть указатель на них. Но иногда данных в самом блоке нет, а есть лишь описание (размер, откуда прочитать и т.п.). Родился следующий (условный) прототип функции


DG>BYTE* get_need_data(const BYTE* source_data, DATA_TYPE type, BYTE* need_data_buf)


DG>- source_data [in] — исходные данные

DG>- type [in] — "критерий" поиска нужных данных
DG>- need_data_buf [out] — буфер, содержащий нужные данные, если они не в source_data

DG>Функция всегда возвращает указатель на нужные данные. Если они находятся внутри source_data, то она вернет указатель, которые указывает внутрь source_data. Если нужных данных внутри source_data нет, она сама выделяет буфер need_data_buf, копирует туда данные и возвращает указатель на этот буфер.


DG>Является ли такой подход естественным? Или, например, лучше разделить эту функцию на две: одна находит данные внутри source_data, а другая читает из вне?


Посмотри, как ты будешь работать с такой функцией:
byte * allocated_data = 0;
byte const * needed_data = get_need_data(source, type, &allocated_data);

// process needed_data...

delete [] allocated_data;

Получается не очень красиво. Работаешь с одними данными, а освобождаешь другие. Связь между ними не ясна.

Тут лучше будет возвращать из функции объект, который сам знает, как себя освободить правильно. Например, хорошо подойдет shared_ptr с нужным deleter.
void array_deleter(byte const * arr)
{
    delete [] arr;
}

void null_deleter(byte const *) {}

shared_ptr<byte const> get_data(byte const * source, data_type type)
{
    if (byte const * found = find_data(source, type))  // нашли?
        return shared_ptr<byte const>(found, null_deleter);

    // иначе создадим
    byte * created = new byte[data_size]; 

    // сразу же отдадим во владение к shared_ptr
    shared_ptr<byte const> result(created, array_deleter);

    // теперь можно заполнять created...

    return result;
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.