Created
August 22, 2015 04:43
-
-
Save Mooophy/389fda07ca51f76ee2a0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /*************************************************************************** | |
| * @file main.cpp | |
| * @author Alan.W | |
| * @date 11 Mar 2014 | |
| * @remark This code is for the exercises from C++ Primer 5th Edition | |
| * @note | |
| ***************************************************************************/ | |
| //! | |
| //! Exercise 18.1: | |
| //! What is the type of the exception object in the following throws? | |
| //! (a) range_error r("error"); | |
| //! throw r; | |
| //! (b) exception *p = &r; | |
| //! throw *p; | |
| // the static, compile-time type of that expression determines the type of | |
| // the exception object. | |
| // so the object thrown the second time is std::exception type not std::range_error. | |
| //! What would happen if the throw in (b) were written as throw p? | |
| // terminate called after throwing an instance of 'std::exception*' | |
| //! | |
| //! Exercise 18.2: Explain what happens if an exception occurs at the indicated point: | |
| /* | |
| void exercise(int *b, int *e) | |
| { | |
| vector<int> v(b, e); | |
| int *p = new int[v.size()]; | |
| ifstream in("ints"); | |
| // exception occurs here | |
| // v and in will bee freed by their destuctors, whereas the object pointed to by p | |
| // won't be freed, aka memory leakage. | |
| } | |
| */ | |
| //! Exercise 18.3: | |
| //! There are two ways to make the previous code work correctly | |
| //! if an exception is thrown. Describe them and implement them. | |
| // 1 RAII | |
| // 2 smart pointer with a custom deleter | |
| //! | |
| #include <iostream> | |
| #include <stdexcept> | |
| #include <memory> | |
| #include <vector> | |
| #include <fstream> | |
| #include <iterator> | |
| //way 1 : RAII | |
| template<typename T> | |
| struct Array | |
| { | |
| explicit Array(std::size_t sz) | |
| : data{ new T[ size ] }, size{ sz } | |
| { } | |
| ~Array() | |
| { | |
| delete[] data; | |
| std::cout << "memory has been freed, using RAII.\n"; | |
| } | |
| T* data; | |
| std::size_t size; | |
| }; | |
| //way 2 : smart pointer | |
| template<typename T> | |
| auto make_shared_array(std::size_t size) -> std::shared_ptr<T> | |
| { | |
| auto deleter = [](T* arr){ | |
| delete[] arr; | |
| std::cout << "memory has been freed, using smart pointer\n"; | |
| }; | |
| return std::shared_ptr<T>(new T[ size ], deleter); | |
| } | |
| void test_way_1(int* b, int* e) | |
| { | |
| std::vector<int> v(b, e); | |
| Array<int> arr{ 42 }; | |
| throw std::runtime_error("exception!"); | |
| } | |
| void test_way_2(int* b, int* e) | |
| { | |
| std::vector<int> v(b, e); | |
| auto arr = make_shared_array<int>(42); | |
| throw std::runtime_error("exception!"); | |
| } | |
| int main() | |
| { | |
| int arr[3] = { 1, 2, 3 }; | |
| try{ | |
| test_way_1(std::begin(arr), std::end(arr)); | |
| } | |
| catch(std::exception const& e) | |
| { | |
| std::cout << e.what() << std::endl; | |
| } | |
| /* | |
| try{ | |
| test_way_2(std::begin(arr), std::end(arr)); | |
| } | |
| catch(std::exception const& e) | |
| { | |
| std::cout << e.what() << std::endl; | |
| } | |
| */ | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment