2012-03-03 40 views
7

Tôi chỉ đang học C++ và muốn ném ngoại lệ, nhưng sau đó kết quả của hàm của tôi sẽ không xác định ???Ném ngoại lệ và trả lại kết quả từ hàm

std::vector<myStruct> extract_notworking(std::vector<myStruct>& avec){ 
     std::vector<myStruct> result; 

     if (avec.size() == 0) 
      //throw domain_error("Cannot operate on empty vector!"); 
      //Cannot use exception for it would yield undefined result 
      return result; 

     //do something here 
     //... 
     return result; 
    } 

Tôi nên làm gì? Trả lại một véc tơ trống? Điều gì sẽ xảy ra nếu tôi ném ngoại lệ cho người nhận giá trị trả lại?

+8

Nếu bạn ném một ngoại lệ, thì chức năng của bạn sẽ không trở lại. Đó là toàn bộ vấn đề. –

+0

Vì vậy, có thể làm cho chức năng của tôi void và thêm một tham số bằng cách tham chiếu đến vector của tôi? – Mihaela

+1

có thể trùng lặp của [Trả lại sau khi ném ngoại lệ] (http://stackoverflow.com/questions/3109943/returning-after-throwing-exceptions) –

Trả lời

9

Khi bạn ném ngoại lệ, chức năng tạm dừng ở đó và thực thi nhảy đến bất cứ nơi nào ngoại lệ bị bắt. Hàm của bạn không trả về bất cứ điều gì vì hàm không trả về.

Bạn chỉ có thể làm

if (avec.empty()) 
    throw domain_error("Cannot operate on empty vector!"); 

Và chức năng của bạn sẽ thoát khỏi đó. Lưu ý rằng bạn không cần phải quan tâm đến giá trị trả về ("Làm thế nào có thể một hàm không trả về bất kỳ thứ gì?") Vì bạn không thể truy cập giá trị trả về của hàm đã ném (và không bắt được).) một ngoại lệ ngay cả khi bạn thử.

Vì vậy, ví dụ, nếu bạn làm

try { 
    std::vector<myStruct> vec; 

    std::vector<myStruct> retval = extract_notworking(vec); 

    print_vector(retval); // this line is only executed if extract_networking 
          // does not throw an exception 
} catch (const domain_error& e) { 
    // we can't access retval here so no worries 
} 

Bạn chỉ có thể truy cập vào retval nếu hàm trả về đúng (ví dụ: không ném). Trong ví dụ này, hàm của bạn sẽ ném vì vec trống, vì vậy print_vector sẽ không bao giờ được gọi.

Thậm chí nếu bạn làm điều này:

std::vector<myStruct> retval; 

try { 
    std::vector<myStruct> vec; 

    retval = extract_notworking(vec); 

    print_vector(retval); 
} catch (const domain_error& e) { 
    // we can access retval here but the assignment never happened 
} 

Kể từ khi chức năng không trở về, sự phân công của giá trị trả về của nó để retval đã không xảy ra, và retval vẫn là một hoàn toàn bình thường mặc định-xây dựng vector mà bạn có thể sử dụng tự do. Vì vậy, trong ví dụ đó, retval không được gán cho và retval không được in, bởi vì extract_networking đã ném ngoại lệ và thực thi nhảy vào khối catch trước khi hai điều đó có thể xảy ra.

+0

Cảm ơn, tôi sẽ ném ngoại lệ và bắt nó trong người gọi. – Mihaela

1

Tôi nên làm gì? Trả lại một véc tơ trống? Điều gì sẽ xảy ra nếu tôi ném ngoại lệ cho người nhận giá trị trả lại?

Điều được trả về từ một hàm không liên quan, vì giá trị trả về sẽ không được sử dụng theo bất kỳ cách nào. Việc thực hiện sẽ tiếp tục ở lần bắt tiếp theo cho ngoại lệ cụ thể đó (tắt khóa học sau khi tháo ngăn xếp).

4

Khi bạn throw ngoại lệ, bạn không thể return và ngược lại. Bạn có thể nghĩ về ngoại lệ như một tổng quát return được thiết kế cho các trường hợp đặc biệt và lỗi.Xem xét chức năng này:

int f(bool b) { 
    if (b) 
     return 42; 
    throw std::runtime_error("Runtime error!"); 
} 

Khi chúng tôi gọi nó là, chúng ta có thể nắm bắt được bình thường giá trị trả về của nó (trong trường hợp này một int) trong một biểu thức, hoặc chúng ta có thể chụp đặc biệt giá trị trở lại của nó (std::runtime_error) sử dụng một khối try với một catch của đúng loại:

try { 

    int normal_result = f(b); 

    // Use normal result. 
    // (Exceptional result does not exist.) 
    std::cout << normal_result << '\n'; 

} catch (const std::exception& exceptional_result) { 

    // Use exceptional result. 
    // (Normal result does not exist.) 
    std::cout << exceptional_result.what() << '\n'; 

} 

sức mạnh của ngoại lệ, tất nhiên, xuất phát từ thực tế là họ tuyên truyền lên các cuộc gọi stack cho đến khi họ đạt được một mat ching catch. Vì vậy, bạn có thể sử dụng chúng để thoát khỏi các cuộc gọi hàm lồng nhau sâu sắc, đồng thời đảm bảo rằng tài nguyên của bạn (bộ nhớ, tệp, & c.) Được quản lý đúng cách.

Các vấn đề liên quan