Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CPlusPlusNotesForProfessionals.pdf
Скачиваний:
47
Добавлен:
20.05.2023
Размер:
5.11 Mб
Скачать

Chapter 15: Flow Control

Section 15.1: case

Introduces a case label of a switch statement. The operand must be a constant expression and match the switch condition in type. When the switch statement is executed, it will jump to the case label with operand equal to the condition, if any.

char c = getchar(); bool confirmed; switch (c) {

case 'y': confirmed = true; break;

case 'n':

confirmed = false; break;

default:

std::cout << "invalid response!\n"; abort();

}

Section 15.2: switch

According to the C++ standard,

The switch statement causes control to be transferred to one of several statements depending on the value of a condition.

The keyword switch is followed by a parenthesized condition and a block, which may contain case labels and an optional default label. When the switch statement is executed, control will be transferred either to a case label with a value matching that of the condition, if any, or to the default label, if any.

The condition must be an expression or a declaration, which has either integer or enumeration type, or a class type with a conversion function to integer or enumeration type.

char c = getchar(); bool confirmed; switch (c) {

case 'y': confirmed = true; break;

case 'n':

confirmed = false; break;

default:

std::cout << "invalid response!\n"; abort();

}

Section 15.3: catch

The catch keyword introduces an exception handler, that is, a block into which control will be transferred when an exception of compatible type is thrown. The catch keyword is followed by a parenthesized exception declaration,

GoalKicker.com – C++ Notes for Professionals

77

which is similar in form to a function parameter declaration: the parameter name may be omitted, and the ellipsis

... is allowed, which matches any type. The exception handler will only handle the exception if its declaration is compatible with the type of the exception. For more details, see catching exceptions.

try {

std::vector<int> v(N);

//do something

}catch (const std::bad_alloc&) {

std::cout << "failed to allocate memory for vector!" << std::endl; } catch (const std::runtime_error& e) {

std::cout << "runtime error: " << e.what() << std::endl; } catch (...) {

std::cout << "unexpected exception!" << std::endl; throw;

}

Section 15.4: throw

1.When throw occurs in an expression with an operand, its e ect is to throw an exception, which is a copy of the operand.

void print_asterisks(int count) { if (count < 0) {

throw std::invalid_argument("count cannot be negative!");

}

while (count--) { putchar('*'); }

}

2.When throw occurs in an expression without an operand, its e ect is to rethrow the current exception. If there is no current exception, std::terminate is called.

try {

//something risky

}catch (const std::bad_alloc&) {

std::cerr << "out of memory" << std::endl; } catch (...) {

std::cerr << "unexpected exception" << std::endl;

// hope the caller knows how to handle this exception throw;

}

3.When throw occurs in a function declarator, it introduces a dynamic exception specification, which lists the types of exceptions that the function is allowed to propagate.

//this function might propagate a std::runtime_error,

//but not, say, a std::logic_error

void risky() throw(std::runtime_error);

// this function can't propagate any exceptions void safe() throw();

Dynamic exception specifications are deprecated as of C++11.

Note that the first two uses of throw listed above constitute expressions rather than statements. (The type of a throw expression is void.) This makes it possible to nest them within expressions, like so:

GoalKicker.com – C++ Notes for Professionals

78

unsigned int predecessor(unsigned int x) {

return (x > 0) ? (x - 1) : (throw std::invalid_argument("0 has no predecessor"));

}

Section 15.5: default

In a switch statement, introduces a label that will be jumped to if the condition's value is not equal to any of the case labels' values.

char c = getchar(); bool confirmed; switch (c) {

case 'y': confirmed = true; break;

case 'n':

confirmed = false; break;

default:

std::cout << "invalid response!\n"; abort();

}

Version ≥ C++11

Defines a default constructor, copy constructor, move constructor, destructor, copy assignment operator, or move assignment operator to have its default behaviour.

class Base {

//...

//we want to be able to delete derived classes through Base*,

//but have the usual behaviour for Base's destructor. virtual ~Base() = default;

};

Section 15.6: try

The keyword try is followed by a block, or by a constructor initializer list and then a block (see here). The try block is followed by one or more catch blocks. If an exception propagates out of the try block, each of the corresponding catch blocks after the try block has the opportunity to handle the exception, if the types match.

std::vector<int> v(N); // if an exception is thrown here,

// it will not be caught by the following catch block

try {

std::vector<int> v(N); // if an exception is thrown here,

// it will be caught by the following catch block

//do something with v

}catch (const std::bad_alloc&) {

//handle bad_alloc exceptions from the try block

Section 15.7: if

Introduces an if statement. The keyword if must be followed by a parenthesized condition, which can be either an expression or a declaration. If the condition is truthy, the substatement after the condition will be executed.

int x;

GoalKicker.com – C++ Notes for Professionals

79

std::cout << "Please enter a positive number." << std::endl; std::cin >> x;

if (x <= 0) {

std::cout << "You didn't enter a positive number!" << std::endl; abort();

}

Section 15.8: else

The first substatement of an if statement may be followed by the keyword else. The substatement after the else keyword will be executed when the condition is falsey (that is, when the first substatement is not executed).

int x; std::cin >> x;

if (x%2 == 0) {

std::cout << "The number is even\n"; } else {

std::cout << "The number is odd\n";

}

Section 15.9: Conditional Structures: if, if..else

if and else:

it used to check whether the given expression returns true or false and acts as such:

if (condition) statement

the condition can be any valid C++ expression that returns something that be checked against truth/falsehood for example:

if (true) { /* code here */ } // evaluate that true is true and execute the code in the brackets if (false) { /* code here */ } // always skip the code since false is always false

the condition can be anything, a function, a variable, or a comparison for example

if(istrue()) { } // evaluate the function, if it returns true, the if will execute the code if(isTrue(var)) { } //evaluate the return of the function after passing the argument var

if(a == b) { } // this will evaluate the return of the experssion (a==b) which will be true if equal and false if unequal

if(a) { } //if a is a boolean type, it will evaluate for its value, if it's an integer, any non zero value will be true,

if we want to check for a multiple expressions we can do it in two ways :

using binary operators :

if (a && b) { } // will be true only if both a and b are true (binary operators are outside the scope here

if (a || b ) { } //true if a or b is true

using if/ifelse/else:

for a simple switch either if or else

if (a== "test") {

GoalKicker.com – C++ Notes for Professionals

80