2012-01-08 3 views
0

Я пытаюсь вернуть функцию boolean и адрес в памяти.Функция возвращает логическое значение и адрес? C++

Я загружаю файл из архива и хотел бы, чтобы он возвращал A., если файл был найден, и B. указатель на файл в памяти после его загрузки. Я понимаю, что у меня нет двух типов возврата, поэтому у меня есть функция как логическая, поэтому она может сказать мне более важно, если файл существует в архиве. Я полагал, что я хотел бы сделать что-то вроде этого:

// Hold the location of the file 
char* location = NULL; 

if(!archive.getFile(name, location)) 
{ 
    errorLog.writeError("Could not find the file!"); 
    return false; 
} 

Если файл не найден, то функция, которая вызывает GetFile возвратит ложь, указывающий файл не был найден. Это отлично работает. Но я пытаюсь выяснить, как напрямую изменить указатель «местоположение» из функции getFile.

Пропускать ли указатель? Или я могу передать адрес указателя и изменить его?

Вот функция в моем заголовке:

bool archive::getFile(string filename, char& location) 

Подведем итоги, я хочу передать в «местоположение» указателя, чтобы она указывала на файл в архиве с функцией GetFile, а затем, когда его возвращает, сможет использовать указатель «location» для доступа к файлу.

спасибо.

ответ

3

Просто верните указатель и нулевой указатель, если вещь не найдена.

char *getFile(std::string name) { 
    return nullptr; // or just 0 
} 

Тогда вы можете сделать:

if ((location = archive.getFile(name)) != 0) { 
    // found 
} 

Но это выглядит как код C. В качестве альтернативы:

  • возвращение пустой std::string в случае ошибки
  • возвращающие логический, но передать неконстантную ссылку на строку

Или действительно передать указатель указатель на или ссылка на указатель, но это наименее «идиоматический» C++, который вы могли бы сделать IMO.

+0

То, что мне нужно. Спасибо. –

+0

Вы также можете создать исключение, если файл не найден. Это позволяет вам более точно контролировать сообщения об ошибках, так как вы можете «вернуть» довольно много разных ошибок. – Thilo

+0

@Thilo: это вопрос мнения, но я бы не стал рассматривать здесь исключение - я предполагаю, что не найти файл в архиве - это то, что должно произойти при нормальных обстоятельствах, поэтому его следует обрабатывать обычным потоком управления , Храните исключения в исключительных условиях. (Но, как сказано, это субъективно/зависит от стандартов контекста/кодирования/окружающего кода и т. Д.) – Mat

1

Вы можете использовать структуру или даже класс, содержащий логические и указатель, который вы хотите вернуть:

struct MyType 
{ 
    bool exist; 
    char* whatever; 
}; 

, а затем ваша функция возвращает MyType-структуру.

+0

Мне очень нравится эта идея. Пока, поскольку я использую структуры, я собираюсь пойти с другими предложениями char *, но спасибо. Я буду помнить, что я могу сделать это в будущем. +1 –

1

Прежде всего объявление вашей функции неверно, оно не должно получать ссылку на char (char &), но указатель на символ. Оно должно быть:

bool archive::getFile(string filename, char* location) 

Если вы хотите изменить указатель вы должны передать указатель на него (т.е. двойной указатель) или ссылка на указатель (который не является хорошим решением, на мой взгляд - микширование ссылки и указатели может запутаться). Так ведь здесь, как декларация должна выглядеть

bool archive::getFile(string filename, char** location) 

В библиотеке стандартного всякий раз, когда возникает необходимость в функции, которая возвращает указатель и указывать кастрированный баран указатель был успешно создан, NULL возвращается на указанный отказ , Таким образом, рассмотреть вопрос о внесении вашей объявление функции:

char* archive::getFile(string filename) 

И сделать его вернуть место, если файл присутствует в архиве и NULL, если это не так.

+0

Спасибо. +1 репутация. –

0

Вы можете поместить два значения в std :: pair. Обычно я предпочитаю, чтобы каждая переменная использовалась только для одного использования, но есть традиция перегрузки указателя с NULL, чтобы означать что-то еще. Если вам нужно вернуть более двух значений, вы можете использовать boost :: tuple.