2016-12-09 5 views
0

Я не слишком разбираюсь в обработке исключений, так что кто-то может помочь мне с этой проблемой? Таким образом, для этой программы, если вы не используете существующий ключ на std :: map, я хочу что-то бросить, но я не знаю, что.Обработка исключений. Как вы выбрали итератор?

ключ карты, если он существует, будет номером телефона (строка), но если он не существует, что бы это было?

class SmartCarrier{ 
private: 
    string carrier_name_; 
    map<string,vector<Message*>> accounts_map; 
public: 
    Search(); 
} 

void phone::Search{ 

    string phone_number; 


    map<string,vector<Message*>>::iterator iter; 


    cout << "Enter a phone number: "; 
    getline(cin,phone_number); 

try{ 
    iter = phone_map.find(phone_number); 

    if (iter ==phone_map.end()) { 
     //Incase of a non-existing phone number what do I throw? 
     throw iter; 
    } 

} 
catch(/*iter ??? what should the block catch as a value?*/){ 
    cout << "Phone number not found." << endl; 
} 
+0

Каков тип 'iter'? Это то, что вам нужно поймать. Не то чтобы в вашем случае это действительно имеет значение, так как оно всегда будет равно 'phone_map.end()'. Я предлагаю вам использовать [один из стандартных классов исключений] (http://en.cppreference.com/w/cpp/error), возможно, составить свой собственный на основе стандартного класса. –

+0

Также для вашей информации: при использовании исключений незначительное влияние на производительность, если исключение не выбрасывается, исключения в C++ действительно оказывают значительное влияние на производительность, если вы его выбрали и поймали. Исключения должны использоваться только в * исключительных случаях. Невозможность проверить ввод пользователя обычно не является таким исключительным случаем. –

+0

Я думаю, что это плохой пример обработки исключений. Вам вообще не нужен блок try-catch. –

ответ

1

Эмпирическое правило - вы всегда бросить производный класс из std::exception, если не указано иное какой стиль руководства. Вы можете использовать уже определенные общие исключения, например std::runtime_error. И передавать данные об ошибках в качестве аргумента исключения, это целая точка исключений - распространять данные об ошибках.

И всегда поймать const-reference.

В вашем случае вы можете просто сделать:

try { 
    auto iter = phone_map.find(phone_number); 
    if (iter == phone_map.end()) { 
     throw std::runtime_error{ "Incorrect phone number" }; 
    } 
} catch(const std::exception& e){ 
    cout << e.what() << endl; 
} 

В вашем случае вы можете бросить итератор, и поймать так:

try { 
    throw phone_map.end(); 
} catch (const map<string,vector<Message*>>::iterator& e) { 
    // Do Something 
} 

Но это не рекомендуется.

0

Я бы сказал, что в этой конкретной ситуации вам не нужно бросать никаких исключений. Имя функции, с точки зрения читателя, вероятно, означает, что единственная ответственность функции состоит в том, чтобы проверить, есть ли такой элемент на карте. Возвращаемое значение по исключению - очень странный (и неэффективный) способ. Здесь я бы использовал std::map::count - он возвращает 1, если такое значение находится на карте, и 0 в противном случае.

Если вам действительно нужно выбросить исключение в случае отсутствия значения, посмотрите на std::map::at(). Он генерирует исключение std::out_of_range, если ключ отсутствует.

Для получения дополнительной информации о std::map::at() и других способах получения информации от std::map см. this.