What good can using exceptions do for me?
Syn vs Asyn
Why?
What?
#include <iostream>
#include <vector>
auto main() -> int {
std::cout << "Enter -1 to quit\n";
std::vector<int> items{97, 84, 72, 65};
std::cout << "Enter an index: ";
for (int print_index; std::cin >> print_index; ) {
if (print_index == -1) break;
std::cout << items.at(print_index) << '\n';
std::cout << "Enter an index: ";
}
}
What does this produce?
*malloc(~~~): cant allocate ? or int printf( )
long strtoul( ) --> erno ERANGE
main() ---> A()--->B()--->C(){return 0 or -1} Can B() or A() handle ?
demo455-exception1.cpp
What does this produce?
#include <iostream>
#include <vector>
auto main() -> int {
std::cout << "Enter -1 to quit\n";
std::vector<int> items{97, 84, 72, 65};
std::cout << "Enter an index: ";
for (int print_index; std::cin >> print_index; ) {
if (print_index == -1) break;
try {
std::cout << items.at(print_index) << '\n';
items.resize(items.size() + 10);
} catch (const std::out_of_range& e) {
std::cout << "Index out of bounds\n";
} catch (...) {
std::cout << "Something else happened";
}
std::cout << "Enter an index: ";
}
}
demo455-exception2.cpp
try {
// Code that may throw an exception
} catch (/* exception type */) {
// Do something with the exception
} catch (...) { // any exception
// Do something with the exception
}
///////////
c(){
if (something happen){throw exception } //action at b and c??
}
B(){
c();
}
This does not mean multiple catches will happen, but rather that multiple options are possible for a single catch
flow? main()--> a(try-catch but different) -->c(throw)
#include <iostream>
#include <vector>
auto main() -> int {
auto items = std::vector<int>{};
try {
items.resize(items.max_size() + 1);
} catch (std::bad_alloc& e) {
std::cout << "Out of bounds.\n";
} catch (std::exception&) {
std::cout << "General exception.\n";
}
}
try {
try {
try {
throw T{};
} catch (T& e1) {
std::cout << "Caught\n";
throw;
}
} catch (T& e2) {
std::cout << "Caught too!\n";
delete ptr;
//throw another type of exception
//overflow might be caused by invalid argument
throw or throw std::invalide_argument();
}
} catch (...) {
delete ptr;
std::cout << "Caught too!!\n";
throw; OR throw std::invalide_argument(); //transfer to another type
}
(Extra reading for those interested)
#include <iostream>
class Giraffe {
public:
Giraffe() { std::cout << "Giraffe constructed" << '\n'; }
Giraffe(const Giraffe &g) { std::cout << "Giraffe copy-constructed" << '\n'; }
~Giraffe() { std::cout << "Giraffe destructed" << '\n'; }
};
void zebra() {
throw Giraffe{};
}
void llama() {
try {
zebra();
} catch (Giraffe g) {
std::cout << "caught in llama; rethrow" << '\n';
throw;
}
}
int main() {
try {
llama();
} catch (Giraffe g) {
std::cout << "caught in main" << '\n';
}
}
demo456-by-value.cpp
#include <iostream>
class Giraffe {
public:
Giraffe() { std::cout << "Giraffe constructed" << '\n'; }
Giraffe(const Giraffe &g) { std::cout << "Giraffe copy-constructed" << '\n'; }
~Giraffe() { std::cout << "Giraffe destructed" << '\n'; }
};
void zebra() {
throw Giraffe{};
}
void llama() {
try {
zebra();
} catch (const Giraffe& g) {
std::cout << "caught in llama; rethrow" << '\n';
throw;
}
}
int main() {
try {
llama();
} catch (const Giraffe& g) {
std::cout << "caught in main" << '\n';
}
}
demo457-by-ref.cpp
Strong& operator=(Strong const& other) {
Strong temp(other);
temp.swap(*this);
return *this;
}
struct DoubleOwnership {
std::unique_ptr<int> pi;
std::unique_ptr<double> pd;
DoubleOwnership(int* pi_, double* pd_) : pi{pi_}, pd{pd_} {}
}; //`std::bad_alloc`
int foo() {
DoubleOwnership object { new int(42), new double(3.14) };
//...
}
What if g() throw exception
C++ classes can be used to avoid such leaks:
C++ provides constructor and destructor
Text
Could not open file, throw exception
class S {
public:
int foo() const; // may throw
}
class S {
public:
int foo() const noexcept; // does not throw
}
CHECK_THROWS(expr);
CHECK_THROWS_AS(expr, type);
REQUIRES_THROWS* also available.
Checks expr throws an exception.
Checks expr throws type (or somthing derived from type).
CHECK_NOTHROW(expr);
Checks expr doesn't throw an exception.
REQUIRES_THROWS* also available.
CHECK_THROWS_MATCHES( expr, type, Matchers::Message("message"));
CHECK_THROWS_AS and CHECK_THROWS_WITH
in a single check.
namespace Matchers = Catch::Matchers;
CHECK_THROWS_WITH( expr, Matchers::Message("message"));
Checks expr throws an exception with a message.