├── Chapter07 ├── a.out ├── 11_function.cpp ├── 14_tail_factorial.cpp ├── 13_to_lowercase.cpp ├── 7_transform_sqrt.cpp ├── 9_function_pointer.cpp ├── 6_precalc_square_roots.cpp ├── 5_square_roots.cpp ├── 12_get_multiplier.cpp ├── 4_count_if.cpp ├── 10_functor.cpp ├── 15_metafactorial.cpp ├── 3_count_evens_functional.cpp ├── 1_count_all_evens.cpp ├── 8_pure_function.cpp └── 2_count_all_evens_short.cpp ├── Chapter03 ├── 14_default_ctor.h ├── 1_spaceship.h ├── 6_empty_struct.cpp ├── 2_product.h ├── 26_inheritance.h ├── 20_lvalue_reference.cpp ├── 19_move_ctor.h ├── 24_quadratic_solver.h ├── 22_encapsulation.h ├── 5_identity.cpp ├── 4_state.cpp ├── 21_move_ctor.h ├── 25_aggregation.h ├── 28_private_inheritance.h ├── 17_custom_copy_ctor.h ├── 3_product.cpp ├── 7_behavior.cpp ├── 15_scope.cpp ├── 9_warehouse.cpp ├── 18_operator_plus.cpp ├── 30_polymorphism.cpp ├── 23_quadratic_solver.cpp ├── 31_singleton.cpp ├── 10_class.h ├── 8_mimicking_class.cpp ├── 16_warehouse.cpp ├── 27_rectangle_square.cpp ├── 11_class_compilers_perspective.h ├── 29_protected_inheritance.h ├── 12_using_class.cpp └── 13_using_class.cpp ├── Chapter01 ├── 10_cmath.cpp ├── 3_concepts.cpp ├── 4_define.cpp ├── 5_define_error.cpp ├── header_example │ ├── rect.cpp │ ├── square.h │ ├── rect.h │ └── main.cpp ├── 8_constexpr_double_it.cpp ├── 6_define_double_it.cpp ├── 7_define_double_it_fixed.cpp ├── 1_checking_argument.cpp └── 9_if_debug.cpp ├── Chapter02 ├── 11_char.cpp ├── 8_recursively_print_number.cpp ├── 6_get_ratio.cpp ├── 3_calling_foo_before_main.cpp ├── 5_auto_deduce.cpp ├── 2_main_with_arguments.cpp ├── 10_types.cpp ├── 4_constructor_call.cpp ├── 9_calculate_max_sum.cpp ├── operations.cpp └── 7_constexpr.cpp ├── Chapter06 ├── 16_tree_node.h ├── 4_node.h ├── 18_unordered_map.cpp ├── 7_list.cpp ├── 6_vector.cpp ├── 13_search_iterators.cpp ├── 12_search_vector.cpp ├── 20_my_string.h ├── 9_distance.cpp ├── 17_insert_hashtable.cpp ├── 14_binary_search.cpp ├── 2_vector.h ├── 5_linked_list.h ├── 8_iterating_containers.cpp ├── 10_distance_2.cpp ├── 11_sort.cpp ├── 1_emails.h ├── 19_graph.h ├── 15_product_comparator.cpp └── 3_vector_puhs_back.h ├── Chapter15 ├── 3_calculate.cpp ├── 4_clusterize.cpp ├── 2_set_examples.cpp └── 1_example.h ├── Chapter12 ├── 4_define.cpp ├── 5_strcpy.cpp ├── 3_networking_start_server.cpp ├── 1_socket.cpp └── 2_networking.h ├── Chapter08 ├── 3_thread_lambda.cpp ├── 2_thread.cpp ├── 9_mutex.cpp ├── 6_thread_raii_2.cpp ├── 4_callable_object.cpp ├── 7_passing_reference.cpp ├── 10_singleton.cpp ├── 5_thread_raii.cpp ├── 1_process_vector.cpp └── 8_thread_pool.cpp ├── Chapter09 ├── 6_atomic.cpp ├── 3_many_threads.cpp ├── 4_locking_counter.cpp ├── 1_connection_manager.cpp ├── 2_double_checked_guard.cpp ├── 7_lockfree_stack.cpp └── 5_thread_safe_stack.cpp ├── Chapter14 ├── 4_mylabel.h ├── 1_sample_app.cpp ├── 2_awesome_button.h ├── 5_example.h ├── 7_resize.cpp ├── 3_widget_example.cpp ├── 8_button.cpp ├── 6_list_widget.cpp └── 9_hboxlayout.cpp ├── Chapter10 ├── 4_generate_username.cpp ├── 2_test_set_email.cpp ├── 1_class_user.h ├── 3_test_set_email.cpp ├── 6_product_hierarchy.h ├── 5_user_with_payment_options.h └── 7_interfaces.h ├── Chapter11 ├── 1_character_unit.h ├── 3_calculate_damage.cpp ├── 4_house.h ├── 7_command.cpp ├── 6_building.h ├── 2_reader.h ├── 5_barrack.h └── 8_prototype.h ├── Chapter13 ├── ch13_rca_compound.cpp ├── ch13_rca_mix_sign_unsigned.cpp ├── ch13_rca_uninit_variable.cpp ├── ch13_dynamic_analysis.cpp ├── ch13_gdb_1.cpp ├── ch13_static_analysis.cpp ├── ch13_gdb_3.cpp ├── ch13_tdd_test.cpp ├── ch13_gdb_2.cpp ├── ch13_tdd_Boost_UTF1.cpp ├── ch13_tdd_v1.h ├── ch13_tdd_v2.h ├── ch13_unit_test10.cpp ├── ch13_unit_test1.cpp ├── ch13_tdd_Boost_UTF2.cpp ├── ch13_tdd_v1.cpp ├── ch13_rca_order_of_evaluation.cpp ├── ch13_tdd_v2.cpp ├── ch13_tdd_v3.h ├── ch13_tdd_Boost_UTF3.cpp └── ch13_tdd_v3.cpp ├── Chapter05 ├── 6_resource_manager.h ├── 9_garbage.cpp ├── 2_delete_array_wrong.cpp ├── 4_delete_array_right_2.cpp ├── 8_shared_ptr.cpp ├── 1_cached_factorial.cpp ├── 10_garbage_collector.h ├── 7_unique_ptr.cpp ├── 3_delete_array_right.cpp └── 5_delete_with_manager.cpp ├── Chapter04 ├── ch4_5_class_template_implicit_inst_B_v2.cpp ├── ch4_5_class_template_implicit_inst_v2.h ├── ch4_5_class_template_implicit_inst_A.cpp ├── ch4_22_polymorphism_metaprogramming.cpp ├── ch4_5_class_template_implicit_inst_C.cpp ├── ch4_5_class_template_implicit_inst.h ├── ch4_17_factorial_traditional.cpp ├── ch4_q_7.cpp ├── ch4_9_none_type_template_param1.cpp ├── ch4_21_polymorphism_traditional.cpp ├── ch4_1_macro_func.cpp ├── ch4_19_loop_unroolling_traditional.cpp ├── ch4_15_traits_boost.cpp ├── ch4_7_variadic_my_min.cpp ├── ch4_5_class_template_implicit_inst_B.cpp ├── ch4_5_class_template_implicit_inst_D.cpp ├── ch4_20_loop_unroolling_metaprogramming.cpp ├── ch4_11_template_template_param.cpp ├── ch4_16_traits_limits.cpp ├── ch4_10_none_type_template_param2.cpp ├── ch4_13_template_template_argument.cpp ├── ch4_14_default_template_arguments.cpp ├── ch4_3_func_template_specialization.cpp ├── ch4_18_factorial_metaprogramming.cpp ├── ch4_2_func_template_implicit_inst.cpp ├── ch4_6_class_template_specialization.cpp ├── ch4_12_template_type_argument.cpp ├── ch4_8_variadic_printf.cpp └── ch4_4_class_template_explicit_inst.cpp ├── Chapter16 ├── query_processor.h └── query-parser.h └── README.md /Chapter07/a.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Expert-CPP/HEAD/Chapter07/a.out -------------------------------------------------------------------------------- /Chapter03/14_default_ctor.h: -------------------------------------------------------------------------------- 1 | class Product { 2 | public: 3 | Product() = default; 4 | // ... 5 | }; -------------------------------------------------------------------------------- /Chapter03/1_spaceship.h: -------------------------------------------------------------------------------- 1 | struct spaceship { 2 | bool is_military; 3 | int speed; 4 | int seats; 5 | }; -------------------------------------------------------------------------------- /Chapter01/10_cmath.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | double result = std::sqrt(49.0); 5 | } 6 | -------------------------------------------------------------------------------- /Chapter03/6_empty_struct.cpp: -------------------------------------------------------------------------------- 1 | struct Empty {}; 2 | 3 | int main() { 4 | Empty e; 5 | std::cout << sizeof(e); 6 | } -------------------------------------------------------------------------------- /Chapter03/2_product.h: -------------------------------------------------------------------------------- 1 | struct Product { 2 | std::string name; 3 | double price; 4 | int rating; 5 | bool available; 6 | }; -------------------------------------------------------------------------------- /Chapter02/11_char.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | char ch = 65; 5 | std::cout << ch << std::endl; 6 | } 7 | -------------------------------------------------------------------------------- /Chapter01/3_concepts.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | template 4 | void make_T( return T(); ) 5 | 6 | int main() {} 7 | -------------------------------------------------------------------------------- /Chapter06/16_tree_node.h: -------------------------------------------------------------------------------- 1 | template 2 | struct tree_node 3 | { 4 | T item; 5 | tree_node* left; 6 | tree_node* right; 7 | }; 8 | -------------------------------------------------------------------------------- /Chapter15/3_calculate.cpp: -------------------------------------------------------------------------------- 1 | int CalculationMachine::calculate(int a, int b) 2 | { 3 | // fptr_ points to the sum() function 4 | return fptr_(a, b); 5 | } -------------------------------------------------------------------------------- /Chapter07/11_function.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void print_it(int a) { 4 | cout << a; 5 | } 6 | 7 | std::function function_object = print_it; -------------------------------------------------------------------------------- /Chapter12/4_define.cpp: -------------------------------------------------------------------------------- 1 | #define DOUBLE_IT(arg) (arg * arg) 2 | 3 | int main() 4 | { 5 | int res = DOUBLE_IT(3 + 1); 6 | std::cout << res << std::endl; 7 | } -------------------------------------------------------------------------------- /Chapter07/14_tail_factorial.cpp: -------------------------------------------------------------------------------- 1 | int tail_factorial(int n, int result) 2 | { 3 | if (n <= 1) return result; 4 | return tail_factorial(n - 1, n * result); 5 | } 6 | -------------------------------------------------------------------------------- /Chapter08/3_thread_lambda.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | std::thread tl{[]{ 5 | std::cout << "A lambda passed to the thread"; 6 | }}; 7 | } 8 | -------------------------------------------------------------------------------- /Chapter03/26_inheritance.h: -------------------------------------------------------------------------------- 1 | class Vehicle { 2 | public: 3 | void move(); 4 | }; 5 | 6 | class Car : public Vehicle { 7 | public: 8 | Car(); 9 | // ... 10 | }; -------------------------------------------------------------------------------- /Chapter09/6_atomic.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | atomic_int m; 7 | m.store(42); 8 | std::cout << m.load(); 9 | } -------------------------------------------------------------------------------- /Chapter01/4_define.cpp: -------------------------------------------------------------------------------- 1 | #define NUMBER 41 2 | #include 3 | 4 | int main() { 5 | int a = NUMBER + 1; 6 | std::cout << a << std::endl; 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /Chapter03/20_lvalue_reference.cpp: -------------------------------------------------------------------------------- 1 | int main() 2 | { 3 | double pi{3.14}; // lvalue 4 | int x{42}; // lvalue 5 | int y{x}; // lvalue 6 | int& ref{x}; // lvalue-reference 7 | } -------------------------------------------------------------------------------- /Chapter01/5_define_error.cpp: -------------------------------------------------------------------------------- 1 | #define NUMBER 41 2 | 3 | struct T {}; 4 | 5 | int main() { 6 | int b = NUMBER + 1; 7 | T t = NUMBER; 8 | 9 | return 0; 10 | } 11 | 12 | -------------------------------------------------------------------------------- /Chapter06/4_node.h: -------------------------------------------------------------------------------- 1 | template 2 | struct node 3 | { 4 | node(const T& it) : item{it}, next{nullptr}, prev{nullptr} {} 5 | T item; 6 | node* next; 7 | node* prev; 8 | }; 9 | -------------------------------------------------------------------------------- /Chapter07/13_to_lowercase.cpp: -------------------------------------------------------------------------------- 1 | std::string str = "lowercase"; 2 | std::transform(str.begin(), str.end(), str.begin(), 3 | [](unsigned char c) { return std::toupper(c); }); 4 | std::cout << str; // "LOWERCASE" -------------------------------------------------------------------------------- /Chapter14/4_mylabel.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class MyLabel : public QLabel 4 | { 5 | Q_OBJECT 6 | public slots: 7 | void setCustomText() { 8 | this->setText("received a signal"); 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /Chapter06/18_unordered_map.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | std::unordered_map hashtable; 6 | hashtable["key1"] = "value 1"; 7 | hashtable["key2"] = "value 2"; 8 | } 9 | -------------------------------------------------------------------------------- /Chapter06/7_list.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | std::list lst; 5 | lst.push_back(4); 6 | lst.push_back(2); 7 | for (const auto& elem : lst) { 8 | std::cout << elem; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Chapter07/7_transform_sqrt.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | std::vector vec{1.1, 2.2, 4.3, 5.6, 2.4}; 7 | auto result = vec | std::ranges::views::transform(std::sqrt); 8 | } -------------------------------------------------------------------------------- /Chapter01/header_example/rect.cpp: -------------------------------------------------------------------------------- 1 | #include "rect.h" 2 | 3 | Rect::Rect(double s1, double s2) 4 | : side1_(s1), side2_(s2) 5 | {} 6 | 7 | const double Rect::get_area() const { 8 | return side1_ * side2_; 9 | } 10 | -------------------------------------------------------------------------------- /Chapter01/header_example/square.h: -------------------------------------------------------------------------------- 1 | #ifndef SQUARE_H 2 | #define SQUARE_H 3 | 4 | #include "rect.h" 5 | 6 | struct Square : Rect 7 | { 8 | Square(double s) : Rect(0.0, 0.0) {} 9 | }; 10 | 11 | #endif // SQUARE_H 12 | -------------------------------------------------------------------------------- /Chapter08/2_thread.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void foo() { 4 | std::cout << "Testing a thread in C++" << std::endl; 5 | } 6 | 7 | int main() { 8 | std::thread test_thread{foo}; 9 | test_thread.join(); 10 | } 11 | -------------------------------------------------------------------------------- /Chapter10/4_generate_username.cpp: -------------------------------------------------------------------------------- 1 | std::string generate_username(const std::string& email) 2 | { 3 | int num = get_random_number(); 4 | std::string local_part = email.substr(0, email.find('@')); 5 | return local_part + num; 6 | } -------------------------------------------------------------------------------- /Chapter06/6_vector.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | std::vector vec; 6 | vec.push_back(4); 7 | vec.push_back(2); 8 | for (const auto& elem : vec) { 9 | std::cout << elem; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Chapter07/9_function_pointer.cpp: -------------------------------------------------------------------------------- 1 | typedef void (*PF)(int); 2 | void foo(int arg) 3 | { 4 | // do something with arg 5 | } 6 | 7 | int bar(int arg, PF f) 8 | { 9 | f(arg); 10 | return arg; 11 | } 12 | 13 | bar(42, foo); -------------------------------------------------------------------------------- /Chapter14/1_sample_app.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char** argv) 4 | { 5 | QApplication app(argc, argv); 6 | 7 | QPushButton btn("Click me!"); 8 | btn.show(); 9 | 10 | return app.exec(); 11 | } -------------------------------------------------------------------------------- /Chapter03/19_move_ctor.h: -------------------------------------------------------------------------------- 1 | class Warehouse { 2 | public: 3 | Warehouse(); // default constructor 4 | Warehouse(const Warehouse&); // copy constructor 5 | Warehouse(Warehouse&&); // move constructor 6 | // code omitted for brevity 7 | }; -------------------------------------------------------------------------------- /Chapter10/2_test_set_email.cpp: -------------------------------------------------------------------------------- 1 | void test_set_email() 2 | { 3 | std::string valid_email = "valid@email.com"; 4 | std::string invalid_email = "112%$"; 5 | User u; 6 | u.set_email(valid_email); 7 | u.set_email(invalid_email); 8 | } 9 | -------------------------------------------------------------------------------- /Chapter11/1_character_unit.h: -------------------------------------------------------------------------------- 1 | class CharacterUnit 2 | { 3 | public: 4 | virtual void attack(const CharacterUnit&) = 0; 5 | virtual void destroy() = 0; 6 | virtual int get_power() const = 0; 7 | virtual int get_life_points() const = 0; 8 | }; -------------------------------------------------------------------------------- /Chapter12/5_strcpy.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | char small_buffer[4]; 7 | const char* long_text = "This text is long enough to overflow small buffers!"; 8 | strcpy(small_buffer, long_text); 9 | } -------------------------------------------------------------------------------- /Chapter13/ch13_rca_compound.cpp: -------------------------------------------------------------------------------- 1 | //ch13_rca_compound.cpp 2 | #include 3 | int f(int x, int y) 4 | { 5 | return x*y; 6 | } 7 | 8 | int main() 9 | { 10 | int x = 3; 11 | std::cout << f(++x, x) << std::endl; //bad,f(4,4) or f(4,3)? 12 | } -------------------------------------------------------------------------------- /Chapter08/9_mutex.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | std::mutex locker; 3 | void inc() { 4 | locker.lock(); 5 | global = global + 1; 6 | locker.unlock(); 7 | } 8 | 9 | int main() 10 | { 11 | std::thread t1{inc}; 12 | std::thread t2{inc}; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter03/24_quadratic_solver.h: -------------------------------------------------------------------------------- 1 | class QuadraticSolver { 2 | public: 3 | QuadraticSolver() = delete; 4 | 5 | static double solve_by_discriminant(double a, double b, double c); 6 | // other solution methods' implementations can be prefixed by "solve_by_" 7 | }; -------------------------------------------------------------------------------- /Chapter01/8_constexpr_double_it.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | constexpr int double_it(int arg) { return arg * arg; } 3 | 4 | int main() { 5 | int good_result = double_it(4 + 1); 6 | std::cout << good_result << std::endl; 7 | 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /Chapter02/8_recursively_print_number.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void print_number(int num) { 4 | if (num > 100) return; 5 | std::cout << num << std::endl; 6 | print_number(num + 1); 7 | } 8 | 9 | int main() { 10 | print_number(1); 11 | } 12 | -------------------------------------------------------------------------------- /Chapter06/13_search_iterators.cpp: -------------------------------------------------------------------------------- 1 | template 2 | int search(Iter first, Iter last, const T& elem) 3 | { 4 | for (std::size_t count = 0; first != last; first++, ++count) { 5 | if (*first == elem) return count; 6 | } 7 | return -1; 8 | } 9 | -------------------------------------------------------------------------------- /Chapter07/6_precalc_square_roots.cpp: -------------------------------------------------------------------------------- 1 | std::vector pure_calc_square_roots(const std::vector& vec) 2 | { 3 | std::vector new_vector; 4 | for (const auto& elem : vec) { 5 | new_vector.push_back(std::sqrt(elem)); 6 | } 7 | return new_vector; 8 | } -------------------------------------------------------------------------------- /Chapter05/6_resource_manager.h: -------------------------------------------------------------------------------- 1 | template 2 | class ResourceManager { 3 | public: 4 | ResourceManager(T* ptr) : ptr_{ptr} {} 5 | ~ResourceManager() { delete ptr_; } 6 | 7 | T& operator*() { return *ptr_; } 8 | T* operator->() { return ptr_; } 9 | }; 10 | -------------------------------------------------------------------------------- /Chapter06/12_search_vector.cpp: -------------------------------------------------------------------------------- 1 | template 2 | int search(const std::vector& vec, const T& item) 3 | { 4 | for (int ix = 0; ix < vec.size(); ++ix) { 5 | if (vec[ix] == item) { 6 | return ix; 7 | } 8 | } 9 | return -1; // not found 10 | } 11 | -------------------------------------------------------------------------------- /Chapter14/2_awesome_button.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class MyAwesomeButton : public QPushButton 4 | { 5 | Q_OBJECT 6 | public: 7 | void keyPressedEvent(QKeyEvent* e) override 8 | { 9 | // anything that we need to do when the button is pressed 10 | } 11 | }; -------------------------------------------------------------------------------- /Chapter02/6_get_ratio.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | auto get_ratio(bool minimum) { 4 | if (minimum) { 5 | return 12; 6 | } 7 | return 18; 8 | } 9 | 10 | auto main() { 11 | std::cout << get_ratio(true) << std::endl; 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter05/9_garbage.cpp: -------------------------------------------------------------------------------- 1 | struct Garbage { 2 | char ch; 3 | int i; 4 | }; 5 | 6 | void foo() { 7 | Garbage* g1 = new Garbage(); 8 | if (true) { 9 | Garbage* g2 = new Garbage(); 10 | } 11 | } 12 | 13 | int main() { 14 | static Garbage* g3 = new Garbage(); 15 | } 16 | -------------------------------------------------------------------------------- /Chapter07/5_square_roots.cpp: -------------------------------------------------------------------------------- 1 | void calc_square_roots(std::vector& vec) 2 | { 3 | for (auto& elem : vec) { 4 | elem = std::sqrt(elem); 5 | } 6 | } 7 | 8 | int main() 9 | { 10 | std::vector vec{1.1, 2.2, 4.3, 5.6, 2.4}; 11 | calc_square_roots(vec); 12 | } -------------------------------------------------------------------------------- /Chapter01/header_example/rect.h: -------------------------------------------------------------------------------- 1 | #ifndef RECT_H 2 | #define RECT_H 3 | 4 | struct Rect 5 | { 6 | private: 7 | double side1_; 8 | double side2_; 9 | 10 | public: 11 | Rect(double s1, double s2); 12 | const double get_area() const; 13 | }; 14 | 15 | #endif // RECT_H 16 | -------------------------------------------------------------------------------- /Chapter04/ch4_5_class_template_implicit_inst_B_v2.cpp: -------------------------------------------------------------------------------- 1 | //file ch4_5_class_template_implicit_inst_B_v2.cpp 2 | #include "ch4_5_class_template_implicit_inst_v2.h" 3 | int main() { 4 | X xi; 5 | xi.f(); 6 | xi.g(); //if un-comment this line, we'll have build errors 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /Chapter06/20_my_string.h: -------------------------------------------------------------------------------- 1 | class my_string 2 | { 3 | public: 4 | my_string(); 5 | // code omitted for brevity 6 | 7 | public: 8 | void insert(char ch); 9 | // code omitted for brevity 10 | 11 | private: 12 | char* buffer_; 13 | int size_; 14 | int capacity_; 15 | }; 16 | -------------------------------------------------------------------------------- /Chapter13/ch13_rca_mix_sign_unsigned.cpp: -------------------------------------------------------------------------------- 1 | //ch13_rca_mix_sign_unsigned.cpp 2 | #include 3 | using namespace std; 4 | int main() 5 | { 6 | int32_t x = 10; 7 | uint32_t y = 20; 8 | uint32_t z = x - y; //z=(uint32_t)x - y 9 | cout << z << endl; //z=4294967286 10 | } 11 | -------------------------------------------------------------------------------- /Chapter03/22_encapsulation.h: -------------------------------------------------------------------------------- 1 | class Warehouse { 2 | public: 3 | // rather naive implementation 4 | void set_size(int sz) { 5 | if (sz < 1) throw std::invalid_argument("Invalid size"); 6 | size_ = sz; 7 | } 8 | // code omitted for brevity 9 | private: 10 | int size_; 11 | }; -------------------------------------------------------------------------------- /Chapter14/5_example.h: -------------------------------------------------------------------------------- 1 | class Example 2 | { 3 | Q_OBJECT: 4 | public: 5 | // member functions 6 | public slots: 7 | // public slots 8 | private slots: 9 | // private slots 10 | signals: // no public, private, or protected 11 | // signals without any definition, only the prototype 12 | }; -------------------------------------------------------------------------------- /Chapter14/7_resize.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char** argv) 4 | { 5 | QApplication app(argc, argv); 6 | 7 | QWidget window; 8 | window.resize(120, 100); 9 | window.setWindowTitle("Mastering C++"); 10 | window.show(); 11 | 12 | return app.exec(); 13 | } -------------------------------------------------------------------------------- /Chapter14/3_widget_example.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char** argv) 4 | { 5 | QApplication app(argc, argv); 6 | 7 | QWidget window; 8 | window.resize(120, 100); 9 | window.setWindowTitle("Mastering C++"); 10 | window.show(); 11 | 12 | return app.exec(); 13 | } -------------------------------------------------------------------------------- /Chapter06/9_distance.cpp: -------------------------------------------------------------------------------- 1 | template 2 | std::size_type distance(Iter first, Iter second) { 3 | if (Iter is a random_access_iterator) { 4 | return second - first; 5 | } 6 | std::size_type count = 0; 7 | for ( ; first != last; ++count, first++) {} 8 | return count; 9 | } 10 | -------------------------------------------------------------------------------- /Chapter08/6_thread_raii_2.cpp: -------------------------------------------------------------------------------- 1 | class thread_RAII 2 | { 3 | public: 4 | explicit thread_RAII(std::thread& t) 5 | : thread_{t} 6 | {} 7 | 8 | ~thread_RAII() 9 | { 10 | if (thread_.joinable()) { 11 | thread_.join(); 12 | } 13 | } 14 | private: 15 | std::thread thread_; 16 | }; 17 | -------------------------------------------------------------------------------- /Chapter11/3_calculate_damage.cpp: -------------------------------------------------------------------------------- 1 | int calculate_damage(const std::vector& units) 2 | { 3 | return std::reduce(units.begin(), units.end(), 0, 4 | [](CharacterUnit& u1, CharacterUnit& u2) { 5 | return u1.get_power() + u2.get_power(); 6 | } 7 | ); 8 | } 9 | -------------------------------------------------------------------------------- /Chapter01/6_define_double_it.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define DOUBLE_IT(arg) (arg * arg) 4 | 5 | int main() { 6 | int st = DOUBLE_IT(4); 7 | std::cout << st << std::endl; 8 | 9 | int bad_result = DOUBLE_IT(4 + 1); 10 | std::cout << bad_result << std::endl; 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter05/2_delete_array_wrong.cpp: -------------------------------------------------------------------------------- 1 | void print_sorted() { 2 | short* arr{new short[420]}; 3 | for (int ix = 0; ix < 420; ++ix) { 4 | std::cin >> arr[ix]; 5 | } 6 | std::sort(arr, arr + 420); 7 | for (int ix = 0; ix < 420; ++ix) { 8 | std::cout << arr[ix]; 9 | } 10 | delete arr; // very bad! 11 | } -------------------------------------------------------------------------------- /Chapter02/3_calling_foo_before_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void foo() { 4 | std::cout << "Risky foo" << std::endl; 5 | } 6 | 7 | // trying to call the foo() outside of the main() function 8 | foo(); 9 | 10 | int main() { 11 | std::cout << "Calling main()" << std::endl; 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter03/5_identity.cpp: -------------------------------------------------------------------------------- 1 | struct Product { 2 | std::string name; 3 | double price; 4 | int rating; 5 | bool available; 6 | }; 7 | 8 | int main() 9 | { 10 | Product book1; 11 | book1.rating = 4; 12 | book1.name = "Book"; 13 | Product book2; 14 | book2.rating = 4; 15 | book2.name = "Book"; 16 | } 17 | -------------------------------------------------------------------------------- /Chapter08/4_callable_object.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class TestTask 4 | { 5 | public: 6 | TestTask() : state{0} 7 | {} 8 | 9 | void operator()() { 10 | state++; 11 | } 12 | 13 | private: 14 | int state; 15 | }; 16 | 17 | int main() { 18 | std::thread t{TestTask()}; 19 | t.join(); 20 | } 21 | -------------------------------------------------------------------------------- /Chapter08/7_passing_reference.cpp: -------------------------------------------------------------------------------- 1 | class big_object {}; 2 | 3 | void make_changes(big_object& b); 4 | 5 | void error_prone() 6 | { 7 | big_object b; 8 | std::thread t{make_changes, b}; 9 | t.join(); 10 | // do something else 11 | } 12 | 13 | int main() 14 | { 15 | std::thread t{make_changes, std::ref(b)}; 16 | } -------------------------------------------------------------------------------- /Chapter13/ch13_rca_uninit_variable.cpp: -------------------------------------------------------------------------------- 1 | //ch13_uninit_variable.cpp 2 | #include 3 | int main() 4 | { 5 | bool x; 6 | // ... //do something else 7 | if (x) { 8 | std::cout << "do A x=" << x << std::endl; 9 | } 10 | else { 11 | std::cout << "do B x=" << x << std::endl; 12 | } 13 | return 0; 14 | } -------------------------------------------------------------------------------- /Chapter03/4_state.cpp: -------------------------------------------------------------------------------- 1 | struct Product { 2 | std::string name; 3 | double price; 4 | int rating; 5 | bool available; 6 | }; 7 | 8 | int main() 9 | { 10 | Product cpp_book; // declaring the object 11 | // changing the state of the object cpp_book 12 | cpp_book.available = true; 13 | cpp_book.rating = 5; 14 | } 15 | -------------------------------------------------------------------------------- /Chapter07/12_get_multiplier.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | std::function get_multiplier() 5 | { 6 | return [](int a, int b) { return a * b; }; 7 | } 8 | 9 | int main() 10 | { 11 | auto multiply = get_multiplier(); 12 | std::cout << multiply(3, 5) << std::endl; // outputs 15 13 | } -------------------------------------------------------------------------------- /Chapter03/21_move_ctor.h: -------------------------------------------------------------------------------- 1 | class Warehouse { 2 | public: 3 | // constructors omitted for brevity 4 | Warehouse(Warehouse&& src) 5 | : size_{src.size_}, 6 | capacity_{src.capacity_}, 7 | products_{src.products_} 8 | { 9 | src.size_ = 0; 10 | src.capacity_ = 0; 11 | src.products_ = nullptr; 12 | } 13 | }; -------------------------------------------------------------------------------- /Chapter03/25_aggregation.h: -------------------------------------------------------------------------------- 1 | class Person; // forward declaration 2 | class Engine { /* code omitted for brevity */ }; 3 | class Car { 4 | public: 5 | Car(); 6 | // ... 7 | private: 8 | Person* driver_; // aggregation 9 | std::vector passengers_; // aggregation 10 | Engine engine_; // composition 11 | // ... 12 | }; -------------------------------------------------------------------------------- /Chapter12/3_networking_start_server.cpp: -------------------------------------------------------------------------------- 1 | void Networking::start_server() 2 | { 3 | // code omitted for brevity (see in the previous snippet) 4 | while (true) { 5 | sockaddr_in client; 6 | int addrlen; 7 | int new_socket = accept(socket_, (sockaddr_in*)&client, &addrlen); 8 | clients_.push_back(client); 9 | } 10 | } -------------------------------------------------------------------------------- /Chapter05/4_delete_array_right_2.cpp: -------------------------------------------------------------------------------- 1 | void print_sorted() { 2 | short* arr{new short[420]}; 3 | for(int ix = 0; ix < 420; ++ix) { 4 | std::cin >> arr[ix]; 5 | if (arr[ix] < 0) { 6 | delete[] arr; 7 | return; 8 | } 9 | } 10 | // sort and print the sorted array, code omitted for brevity 11 | delete[] arr; 12 | } -------------------------------------------------------------------------------- /Chapter01/header_example/main.cpp: -------------------------------------------------------------------------------- 1 | #if __has_include("custom_io_stream.h") 2 | #include "custom_io_stream.h") 3 | #else 4 | #include 5 | #endif 6 | 7 | #include "rect.h" 8 | #include "square.h" 9 | 10 | int main() { 11 | Rect r(3.1, 4.05); 12 | std::cout << r.get_area() << std::endl; 13 | 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /Chapter02/5_auto_deduce.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | auto foo() -> int 4 | { 5 | std::cout << "foo in alternative syntax" << std::endl; 6 | return true; 7 | } 8 | 9 | auto foo14() { 10 | std::cout << "In C++14 syntax" << std::endl; 11 | return 0; 12 | } 13 | 14 | int main() { 15 | foo(); 16 | foo14(); 17 | } 18 | -------------------------------------------------------------------------------- /Chapter07/4_count_if.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | std::array arr{1, 2, 3, 4}; 8 | auto res = std::count_if(arr.cbegin(), arr.cend(), 9 | [](int x){ return x == 3; }); 10 | std::cout << "There are " << res << " number of elements equal to 3" << std::endl; 11 | } -------------------------------------------------------------------------------- /Chapter13/ch13_dynamic_analysis.cpp: -------------------------------------------------------------------------------- 1 | //ch13_dynamic_analysis.cpp 2 | #include 3 | int main() 4 | { 5 | int n=10; 6 | 7 | //leak: free() is not cialled 8 | float *p = (float *)malloc(n * sizeof(float)); 9 | for( int i=0; i 2 | 3 | int main(int argc, char** argv) { 4 | std::cout << "The number of passed arguments is: " << argc << std::endl; 5 | std::cout << "Arguments are: " << std::endl; 6 | for (int ix = 1; ix < argc; ++ix) { 7 | std::cout << argv[ix] << std::endl; 8 | } 9 | 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /Chapter09/3_many_threads.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int counter = 0; 4 | 5 | void foo() 6 | { 7 | counter++; 8 | } 9 | 10 | int main() 11 | { 12 | std::jthread A{foo}; 13 | std::jthread B{foo}; 14 | std::jthread C{[]{foo();}}; 15 | std::jthread D{ 16 | []{ 17 | for (int ix = 0; ix < 10; ++ix) { foo(); } 18 | } 19 | }; 20 | } -------------------------------------------------------------------------------- /Chapter13/ch13_gdb_1.cpp: -------------------------------------------------------------------------------- 1 | //ch13_gdb_1.cpp 2 | #include 3 | float multiple(float x, float y); 4 | int main() 5 | { 6 | float x = 10, y = 20; 7 | float z = multiple(x, y); 8 | printf("x=%f, y=%f, x*y = %f\n", x, y, z); 9 | return 0; 10 | } 11 | 12 | float multiple(float x, float y) 13 | { 14 | float s = x + y; 15 | return s; 16 | } 17 | 18 | -------------------------------------------------------------------------------- /Chapter14/8_button.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char** argv) 4 | { 5 | QApplication app(argc, argv); 6 | 7 | QWidget window; 8 | window.resize(120, 100); 9 | window.setWindowTitle("Mastering C++"); 10 | window.show(); 11 | 12 | QPushButton* btn = new QPushButton("Click me!", &window); 13 | 14 | return app.exec(); 15 | } -------------------------------------------------------------------------------- /Chapter03/28_private_inheritance.h: -------------------------------------------------------------------------------- 1 | class Square : private Rectangle { 2 | public: 3 | void set_side(int side) { 4 | // Rectangle's public interface is accessible to the Square 5 | set_width(side); 6 | set_height(side); 7 | } 8 | int area() { 9 | area_ = Rectangle::area(); 10 | return area_; 11 | } 12 | private: 13 | int area_; 14 | }; 15 | -------------------------------------------------------------------------------- /Chapter03/17_custom_copy_ctor.h: -------------------------------------------------------------------------------- 1 | class Warehouse { 2 | public: 3 | // ... 4 | Warehouse(const Warehouse& rhs) { 5 | size_ = rhs.size_; 6 | capacity_ = rhs.capacity_; 7 | products_ = new Product[capacity_]; 8 | for (int ix = 0; ix < size_; ++ix) { 9 | products_[ix] = rhs.products_[ix]; 10 | } 11 | } 12 | // code omitted for brevity 13 | }; -------------------------------------------------------------------------------- /Chapter05/8_shared_ptr.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct Product 4 | { 5 | // ... 6 | }; 7 | 8 | void print_name(std::shared_ptr apple) { 9 | std::cout << apple->name(); 10 | } 11 | 12 | int main() 13 | { 14 | std::shared_ptr res{new Product}; 15 | res->set_name("Red apple"); 16 | print_name(res); 17 | res->set_price(0.42); 18 | } 19 | -------------------------------------------------------------------------------- /Chapter04/ch4_5_class_template_implicit_inst_v2.h: -------------------------------------------------------------------------------- 1 | //file ch4_5_class_template_implicit_inst_v2.h 2 | #ifndef __CH4_5_H__ 3 | #define __CH4_5_H__ 4 | #include 5 | template 6 | class X { 7 | public: 8 | X() = default; 9 | ~X() = default; 10 | void f() { std::cout << "X::f()" << std::endl; }; 11 | void g() { blabla; }; 12 | }; 13 | #endif 14 | 15 | -------------------------------------------------------------------------------- /Chapter01/7_define_double_it_fixed.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // added additional parentheses around the arg 4 | #define DOUBLE_IT(arg) ((arg) * (arg)) 5 | 6 | int main() { 7 | int st = DOUBLE_IT(4); 8 | std::cout << st << std::endl; 9 | 10 | int bad_result = DOUBLE_IT(4 + 1); 11 | std::cout << bad_result << std::endl; 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /Chapter02/10_types.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Point { 5 | float x; 6 | float y; 7 | }; 8 | 9 | int main() { 10 | std::cout << std::is_fundamental_v << " " 11 | << std::is_fundamental_v << " " 12 | << std::is_compound_v << " " 13 | << std::is_compound_v << std::endl; 14 | } 15 | -------------------------------------------------------------------------------- /Chapter05/1_cached_factorial.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | std::unordered_map cache; 5 | 6 | long factorial(long n) { 7 | if (n <= 1) return 1; 8 | if (cache.contains(n)) return cache[n]; 9 | cache[n] = n * factorial(n - 1); 10 | return cache[n]; 11 | } 12 | 13 | int main() 14 | { 15 | std::cout << factorial(5) << std::endl; 16 | } 17 | -------------------------------------------------------------------------------- /Chapter02/4_constructor_call.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct BeforeMain { 4 | BeforeMain() { 5 | std::cout << "Constructing BeforeMain" << std::endl; 6 | test(); 7 | } 8 | void test() {std::cout << "test" << std::endl;} 9 | }; 10 | 11 | BeforeMain b; 12 | 13 | int main() { 14 | std::cout << "Calling main()" << std::endl; 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /Chapter02/9_calculate_max_sum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int sum(int n, int m) { return n + m; } 4 | int max(int x, int y) { 5 | int max = x > y ? x : y; 6 | return max; 7 | } 8 | int calculate(int a, int b) { 9 | return sum(a, b) + max(a, b); 10 | } 11 | 12 | int main() { 13 | auto result = calculate(11, 22); 14 | std::cout << "result == " << result << std::endl; 15 | } 16 | -------------------------------------------------------------------------------- /Chapter04/ch4_5_class_template_implicit_inst_A.cpp: -------------------------------------------------------------------------------- 1 | //file ch4_5_class_template_implicit_inst_A.cpp 2 | #include "ch4_5_class_template_implicit_inst.h" 3 | int main() 4 | { 5 | X xi; //implicit instantiation generates class X, then create object xi 6 | X xf; //implicit instantiation generates class X, then create object xf 7 | return 0; 8 | } 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Chapter03/3_product.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Product { 5 | std::string name; 6 | double price; 7 | int rating; 8 | bool available; 9 | }; 10 | 11 | int main() 12 | { 13 | Product book; 14 | Product tshirt; 15 | Product* ptr = &book; 16 | Product& ref = tshirt; 17 | book.name = "Expert C++"; 18 | std::cout << ptr->name << std::endl; 19 | } 20 | -------------------------------------------------------------------------------- /Chapter03/7_behavior.cpp: -------------------------------------------------------------------------------- 1 | struct Product { 2 | std::string name; 3 | double price; 4 | int rating; 5 | bool available; 6 | }; 7 | 8 | void set_rating(Product* p, int r) { 9 | if (r >= 1 && r <= 5) { 10 | p->rating = r; 11 | } 12 | // otherwise ignore 13 | } 14 | 15 | int main() 16 | { 17 | Product cpp_book; 18 | set_rating(&cpp_book, -12); // won't change the state 19 | } 20 | -------------------------------------------------------------------------------- /Chapter04/ch4_22_polymorphism_metaprogramming.cpp: -------------------------------------------------------------------------------- 1 | //ch4_22_polymorphism_metaprogramming.cpp 2 | #include 3 | template struct B { 4 | void ui() { 5 | static_cast(this)->alg(); 6 | } 7 | }; 8 | 9 | struct D : B { 10 | void alg() { 11 | std::cout << "D::alg()" << std::endl; 12 | } 13 | }; 14 | 15 | int main() { 16 | B b; 17 | b.ui(); 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /Chapter07/10_functor.cpp: -------------------------------------------------------------------------------- 1 | class Function 2 | { 3 | public: 4 | void modify_state(int a) { 5 | state_ = a; 6 | } 7 | 8 | int get_state() { 9 | return state_; 10 | } 11 | 12 | void operator()() { 13 | // do something that a function would do 14 | } 15 | private: 16 | int state_; 17 | }; 18 | 19 | void foo(Function f) 20 | { 21 | f(); 22 | // some other useful code 23 | } -------------------------------------------------------------------------------- /Chapter04/ch4_5_class_template_implicit_inst_C.cpp: -------------------------------------------------------------------------------- 1 | //file ch4_5_class_template_implicit_inst_C.cpp 2 | #include "ch4_5_class_template_implicit_inst.h" 3 | int main() 4 | { 5 | X *p_xi; //instantiation of class X is not required, since p_xi is pointer object 6 | X *p_xf; //instantiation of class X is not required, since p_xf is pointer object 7 | return 0; 8 | } 9 | 10 | 11 | -------------------------------------------------------------------------------- /Chapter01/1_checking_argument.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | auto takes_positive(int arg) { 5 | if (arg < 0) { 6 | throw std::invalid_argument("Is negative"); 7 | } 8 | return 1; 9 | } 10 | 11 | int main() { 12 | try { 13 | takes_positive(-4); 14 | } catch (std::exception& e) { 15 | std::cout << e.what() << std::endl; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chapter06/17_insert_hashtable.cpp: -------------------------------------------------------------------------------- 1 | template 2 | int hash(const T& key) 3 | { 4 | // generate and return and efficient 5 | // hash value from key based on the key's type 6 | } 7 | 8 | template 9 | void insert_into_hashtable(const T& key, const U& value) 10 | { 11 | int index = hash(key); 12 | hash_table[index].push_back(value); // insert into the list 13 | } 14 | -------------------------------------------------------------------------------- /Chapter07/15_metafactorial.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct MetaFactorial 3 | { 4 | enum { 5 | value = N * MetaFactorial::value 6 | }; 7 | }; 8 | 9 | template <> 10 | struct MetaFactorial<0> 11 | { 12 | enum { 13 | value = 1 14 | }; 15 | }; 16 | 17 | int main() { 18 | std::cout << MetaFactorial<5>::value; // outputs 120 19 | std::cout << MetaFactorial<6>::value; // outputs 720 20 | } 21 | -------------------------------------------------------------------------------- /Chapter04/ch4_5_class_template_implicit_inst.h: -------------------------------------------------------------------------------- 1 | //file ch4_5_class_template_implicit_inst.h 2 | #ifndef __CH4_5_H__ 3 | #define __CH4_5_H__ 4 | #include 5 | template 6 | class X { 7 | public: 8 | X() = default; 9 | ~X() = default; 10 | void f() { std::cout << "X::f()" << std::endl; }; 11 | void g() { std::cout << "X::g()" << std::endl; }; 12 | void h() { error; }; 13 | }; 14 | #endif 15 | 16 | -------------------------------------------------------------------------------- /Chapter05/10_garbage_collector.h: -------------------------------------------------------------------------------- 1 | class GarbageCollector { 2 | public: 3 | template 4 | static T* allocate() { 5 | T* ptr = new T(); 6 | objects_[ptr] = true; 7 | return ptr; 8 | } 9 | 10 | static void deallocate(T* p) { 11 | if (objects_[p]) { 12 | objects_[p] = false; 13 | delete p; 14 | } 15 | } 16 | 17 | private: 18 | std::unordered_map objects_; 19 | }; 20 | -------------------------------------------------------------------------------- /Chapter09/4_locking_counter.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int counter = 0; 5 | std::mutex m; 6 | 7 | void foo() 8 | { 9 | std::lock_guard g{m}; 10 | counter++; 11 | } 12 | 13 | int main() 14 | { 15 | std::jthread A{foo}; 16 | std::jthread B{foo}; 17 | std::jthread C{[]{foo();}}; 18 | std::jthread D{ 19 | []{ 20 | for (int ix = 0; ix < 10; ++ix) { foo(); } 21 | } 22 | }; 23 | } -------------------------------------------------------------------------------- /Chapter04/ch4_17_factorial_traditional.cpp: -------------------------------------------------------------------------------- 1 | //ch4_17_factorial_recursion.cpp 2 | #include 3 | uint32_t f1(const uint32_t n) { 4 | return (n<=1) ? 1 : n * f1(n - 1); 5 | } 6 | 7 | constexpr uint32_t f2(const uint32_t n) { 8 | return ( n<=1 )? 1 : n * f2(n - 1); 9 | } 10 | 11 | int main() { 12 | uint32_t a1 = f1(10); 13 | const uint32_t a2 = f2(10); 14 | std::cout << "a1=" << a1 << ", a2=" << a2 << std::endl; 15 | } 16 | -------------------------------------------------------------------------------- /Chapter06/14_binary_search.cpp: -------------------------------------------------------------------------------- 1 | template 2 | std::size_t binsearch(const std::vector& vec, const T& item, int start, int end) 3 | { 4 | if (start > end) return -1; 5 | int mid = start + (end - start) / 2; 6 | if (vec[mid] == item) { 7 | return mid; // found 8 | } 9 | if (vec[mid] > item) { 10 | return binsearch(vec, item, start, mid - 1); 11 | } 12 | return binsearch(vec, item, mid + 1, end); 13 | } 14 | -------------------------------------------------------------------------------- /Chapter03/15_scope.cpp: -------------------------------------------------------------------------------- 1 | class Product { 2 | public: 3 | Product() = default; 4 | // ... 5 | }; 6 | 7 | static Product global_prod; 8 | 9 | Product* foo() { 10 | Product* heap_prod = new Product(); 11 | heap_prod->name = "Sample"; 12 | return heap_prod; 13 | } 14 | 15 | int main() { 16 | Product stack_prod; 17 | if (true) { 18 | Product tmp; 19 | tmp.rating = 3; 20 | } 21 | stack_prod.price = 4.2; 22 | foo(); 23 | } -------------------------------------------------------------------------------- /Chapter09/1_connection_manager.cpp: -------------------------------------------------------------------------------- 1 | namespace Db { 2 | class ConnectionManager 3 | { 4 | public: 5 | static std::shared_ptr get_instance() 6 | { 7 | if (instance_ == nullptr) { 8 | instance_.reset(new ConnectionManager()); 9 | } 10 | return instance_; 11 | } 12 | 13 | // Database connection related code omitted 14 | private: 15 | static std::shared_ptr instance_{nullptr}; 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /Chapter04/ch4_q_7.cpp: -------------------------------------------------------------------------------- 1 | //file ch4_5_class_template_implicit_inst_B_v2.c 2 | #include 3 | template 4 | inline double f(const double x) { 5 | return f(x) * x; 6 | } 7 | template<> 8 | inline double f<1>(const double x) { 9 | return x; 10 | } 11 | template<> 12 | inline double f<0>(const double x) { 13 | return 1.0; 14 | } 15 | 16 | int main() { 17 | std::cout << f<32>(2.0) << std::endl; 18 | return 0; 19 | } 20 | 21 | -------------------------------------------------------------------------------- /Chapter08/10_singleton.cpp: -------------------------------------------------------------------------------- 1 | class MySingleton 2 | { 3 | public: 4 | static MySingleton* get_instance() { 5 | if (instance_ == nullptr) { 6 | std::lock_guard lg{mutex_}; 7 | if (instance_ == nullptr) { 8 | instance_ = new MySingleton(); 9 | } 10 | } 11 | return instance_; 12 | } 13 | 14 | // code omitted for brevity 15 | private: 16 | std::mutex mutex_; 17 | static MySingleton* instance_; 18 | } 19 | -------------------------------------------------------------------------------- /Chapter01/9_if_debug.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | // #define DEBUG 1 4 | 5 | void log(const std::string& msg) { 6 | #if DEBUG 7 | std::cout << msg << std::endl; 8 | #endif 9 | } 10 | 11 | void foo() { 12 | log("foo() called"); 13 | // do some useful job 14 | } 15 | 16 | void start() { 17 | log("start() called"); 18 | foo(); 19 | // do some useful job 20 | } 21 | 22 | int main() { 23 | start(); 24 | } 25 | -------------------------------------------------------------------------------- /Chapter08/5_thread_raii.cpp: -------------------------------------------------------------------------------- 1 | class thread_RAII 2 | { 3 | public: 4 | explicit thread_RAII(std::thread& t) 5 | : thread_{t} 6 | {} 7 | 8 | ~thread_RAII() { 9 | thread_.join(); 10 | } 11 | 12 | private: 13 | std::thread thread_; 14 | }; 15 | 16 | void foo() { 17 | std::cout << "Testing thread join"; 18 | } 19 | 20 | int main() { 21 | std::thread t{foo}; 22 | thread_RAII r{t}; 23 | // will automatically join the thread 24 | } 25 | -------------------------------------------------------------------------------- /Chapter11/4_house.h: -------------------------------------------------------------------------------- 1 | class House 2 | { 3 | public: 4 | House(); 5 | // copying will be covered by a Prototype 6 | House(const House&) = delete; 7 | House& operator=(const House&) = delete; 8 | 9 | public: 10 | void attack(const CharacterUnit&); 11 | void destroy(); 12 | void build(const CharacterUnit&); 13 | // ... 14 | 15 | private: 16 | int life_points_; 17 | int capacity_; 18 | std::chrono::duration construction_duration_; 19 | }; -------------------------------------------------------------------------------- /Chapter03/9_warehouse.cpp: -------------------------------------------------------------------------------- 1 | struct Warehouse { 2 | Product* products; 3 | int capacity; 4 | int size; 5 | }; 6 | 7 | void initialize_warehouse(Warehouse* w) { 8 | w->capacity = 1000; 9 | w->size = 0; 10 | w->products = new Product[w->capacity]; 11 | for (int ix = 0; ix < w->capacity; ++ix) { 12 | initialize(&w->products[ix]); // initialize each Product object 13 | } 14 | } 15 | 16 | void set_size(int size) { ... } 17 | // code omitted for brevity -------------------------------------------------------------------------------- /Chapter16/query_processor.h: -------------------------------------------------------------------------------- 1 | struct Document { 2 | // place document related fields here 3 | }; 4 | 5 | class QueryProcessor 6 | { 7 | public: 8 | using Documents = std::vector; 9 | static Documents process_query(const Query& query) { 10 | if (!query.dialog_id.empty()) { 11 | // request the knowledge graph for new terms 12 | } 13 | // retrieve documents from the index 14 | // sort and return documents 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /Chapter05/7_unique_ptr.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct Product 4 | { 5 | // ... 6 | }; 7 | 8 | void print_name(std::unique_ptr apple) { 9 | std::cout << apple->name(); 10 | } 11 | 12 | int main() 13 | { 14 | std::unique_ptr res{new Product}; 15 | res->set_name("Red apple"); 16 | 17 | 18 | std::unique_ptr res{new Product}; 19 | res->set_name("Red apple"); 20 | print_name(res); 21 | res->set_price(0.42); 22 | } 23 | -------------------------------------------------------------------------------- /Chapter11/7_command.cpp: -------------------------------------------------------------------------------- 1 | class Command 2 | { 3 | public: 4 | Command() : called_(0) {} 5 | 6 | void operator()() { 7 | ++called_; 8 | std::cout << "I'm a smart function." << std::endl; 9 | std::cout << "I've been called << called_ " << " times." << std::endl; 10 | } 11 | 12 | private: 13 | int called_; 14 | }; 15 | 16 | int main() 17 | { 18 | Command c1; 19 | Command c2; 20 | c1(); 21 | c1(); 22 | c2(); 23 | c2(); 24 | c2(); 25 | } -------------------------------------------------------------------------------- /Chapter02/operations.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() { 6 | int arr[]{1, 2, 3, 4}; 7 | std::unordered_map > operations; 8 | operations['+'] = [](int a, int b) { return a + b; }; 9 | operations['-'] = [](int a, int b) { return a - b; }; 10 | for (auto& op: operations) { 11 | std::cout << op.second(10, 20) << std::endl; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /Chapter04/ch4_9_none_type_template_param1.cpp: -------------------------------------------------------------------------------- 1 | //ch4_9_none_type_template_param1.cpp 2 | #include 3 | template 4 | class V { 5 | public: 6 | V(int init) { 7 | for (int i = 0; i x(1); //x.a is an array of 5 int, initialized as all 1's 15 | x.a[4] = 10; 16 | for( auto &e : x.a) { 17 | std::cout << e << std::endl; 18 | } 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /Chapter11/6_building.h: -------------------------------------------------------------------------------- 1 | class Building 2 | { 3 | public: 4 | virtual void attack(const CharacterUnit&) = 0; 5 | virtual void destroy() = 0; 6 | virtual void build(CharacterUnit*) = 0; 7 | virtual int get_life_points() const = 0; 8 | 9 | public: 10 | void run() { 11 | std::jthread{Building::background_action_, this}; 12 | } 13 | 14 | private: 15 | virtual void background_action_() { 16 | // no or default implementation in the base class 17 | } 18 | }; -------------------------------------------------------------------------------- /Chapter14/6_list_widget.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char** argv) 4 | { 5 | QApplication app(argc, argv); 6 | QListWidget* listWgt{new QListWidget}; 7 | new QListWidgetItem("Amat", listWgt); 8 | new QListWidgetItem("Samvel", listWgt); 9 | new QListWidgetItem("Leia", listWgt); 10 | 11 | QListWidgetItem* newName{new QListWidgetItem}; 12 | newName->setText("Sveta"); 13 | listWgt->insertItem(0, newName); 14 | 15 | return app.exec(); 16 | } -------------------------------------------------------------------------------- /Chapter02/7_constexpr.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int double_it(int number) { 4 | return number * 2; 5 | } 6 | 7 | constexpr int triple_it(int number) { 8 | return number * 3; 9 | } 10 | 11 | int main() { 12 | int test = 42; 13 | int doubled = double_it(test); 14 | int tripled = triple_it(test); 15 | std::cin >> test; 16 | int another_tripled = triple_it(test); 17 | std::cout << tripled << std::endl; 18 | std::cout << another_tripled << std::endl; 19 | } 20 | -------------------------------------------------------------------------------- /Chapter13/ch13_static_analysis.cpp: -------------------------------------------------------------------------------- 1 | //ch13_static_analysis.cpp 2 | #include 3 | int *getPointer(void) 4 | { 5 | return 0; 6 | } 7 | 8 | int &getVal() { 9 | int x = 5; 10 | return x; 11 | } 12 | 13 | int main() 14 | { 15 | int *x = getPointer(); 16 | if( x> 0 ){ 17 | *x = 5; 18 | } 19 | else{ 20 | std::cout << "x is null" << std::endl; 21 | } 22 | 23 | int &y = getVal(); 24 | std::cout << y << std::endl; 25 | 26 | return 0; 27 | } 28 | 29 | -------------------------------------------------------------------------------- /Chapter05/3_delete_array_right.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void print_sorted() { 4 | short* arr{new short[4]}; 5 | for (int ix = 0; ix < 4; ++ix) { 6 | std::cin >> arr[ix]; 7 | if (arr[ix] < 0) return; 8 | } 9 | std::sort(arr, arr + 4); 10 | for (int ix = 0; ix < 4; ++ix) { 11 | std::cout << arr[ix] << " "; 12 | if (arr[ix] < 0) return; 13 | } 14 | std::cout << std::endl; 15 | delete[] arr; 16 | } 17 | 18 | int main() { 19 | print_sorted(); 20 | } 21 | -------------------------------------------------------------------------------- /Chapter08/1_process_vector.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void process_vector(const std::vector& vec) 4 | { 5 | // calculate the sum and print it 6 | } 7 | 8 | int main() 9 | { 10 | std::vector vec1{1, 2, 3, 4, 5}; 11 | std::vector vec2{6, 7, 8, 9, 10}; 12 | std::vector vec3{11, 12, 13, 14, 15}; 13 | process_vector(vec1); // takes A amount of time 14 | process_vector(vec2); // takes A amount of time 15 | process_vector(vec3); // takes A amount of time 16 | } 17 | -------------------------------------------------------------------------------- /Chapter06/2_vector.h: -------------------------------------------------------------------------------- 1 | template 2 | class Vector 3 | { 4 | public: 5 | Vector() : buffer_{nullptr}, capacity_{2}, size_{0} 6 | { 7 | buffer_ = new T[capacity_]; // initializing an empty array 8 | } 9 | ~Vector() { delete [] buffer_; } 10 | // code omitted for brevity 11 | 12 | public: 13 | void push_back(const T& item) 14 | { 15 | if (size_ == capacity_) { 16 | // resize 17 | } 18 | buffer_[size_++] = item; 19 | } 20 | // code omitted for brevity 21 | }; 22 | -------------------------------------------------------------------------------- /Chapter06/5_linked_list.h: -------------------------------------------------------------------------------- 1 | template 2 | class LinkedList 3 | { 4 | // code omitted for brevity 5 | public: 6 | void push_front(const T& item) 7 | { 8 | node* new_node = new node{item}; 9 | if (head_ != nullptr) { 10 | new_node->next = head_->next; 11 | if (head_->next != nullptr) { 12 | head_->next->prev = new_node; 13 | } 14 | } 15 | new_node->next = head_; 16 | head_ = new_node; 17 | } 18 | private: 19 | node* head_; 20 | }; 21 | -------------------------------------------------------------------------------- /Chapter15/4_clusterize.cpp: -------------------------------------------------------------------------------- 1 | struct Object 2 | { 3 | int color; 4 | int shape; 5 | int width; 6 | int height; 7 | }; 8 | 9 | using objects_list = std::vector; 10 | using categorized_table = std::unordered_map; 11 | 12 | categorized_table clusterize(const objects_list& objects) 13 | { 14 | categorized_table result; 15 | for (const auto& obj : objects) { 16 | result[obj.color].push_back(obj); 17 | result[obj.shape].push_back(obj); 18 | } 19 | return result; 20 | } -------------------------------------------------------------------------------- /Chapter06/8_iterating_containers.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | std::vector vec; 7 | vec.push_back(4); 8 | vec.push_back(2); 9 | std::vector::iterator it = vec.begin(); 10 | std::cout << *it; // 4 11 | it++; 12 | std::cout << *it; // 2 13 | 14 | std::list lst; 15 | lst.push_back(4); 16 | lst.push_back(2); 17 | std::list::iterator lit = lst.begin(); 18 | std::cout << *lit; // 4 19 | lit++; 20 | std::cout << *lit; // 2 21 | } 22 | -------------------------------------------------------------------------------- /Chapter03/18_operator_plus.cpp: -------------------------------------------------------------------------------- 1 | // considering declared as friend in the Warehouse class 2 | Warehouse operator+(const Warehouse& a, const Warehouse& b) { 3 | Warehouse sum; // temporary 4 | sum.size_ = a.size_ + b.size_; 5 | sum.capacity_ = a.capacity_ + b.capacity_; 6 | sum.products_ = new Product[sum.capacity_]; 7 | for (int ix = 0; ix < a.size_; ++ix) { sum.products_[ix] = a.products_[ix]; } 8 | for (int ix = 0; ix < b.size_; ++ix) { sum.products_[a.size_ + ix] = b.products_[ix]; } 9 | return sum; 10 | } -------------------------------------------------------------------------------- /Chapter13/ch13_gdb_3.cpp: -------------------------------------------------------------------------------- 1 | //ch13_gdb_3.cpp 2 | #include 3 | #include 4 | void foo( const int n ) 5 | { 6 | int* p = (int *)malloc(n * sizeof(int) ); 7 | //for( int i=0; ialg(); //outputs "alg() in D" 19 | delete p; 20 | return 0; 21 | } -------------------------------------------------------------------------------- /Chapter06/10_distance_2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | template 5 | typename std::iterator_traits::difference_type distance(Iter first, Iter last) 6 | { 7 | using category = std::iterator_traits::iterator_category; 8 | if constexpr (std::is_same_v) { 9 | return last - first; 10 | } 11 | typename std::iterator_traits::difference_type count; 12 | for (; first != last; ++count, first++) {} 13 | return count; 14 | } 15 | -------------------------------------------------------------------------------- /Chapter06/11_sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main() 7 | { 8 | std::vector vec; 9 | // insert elements into the vector 10 | vec.push_back(4); 11 | vec.push_back(11); 12 | vec.push_back(9); 13 | for (auto& v : vec) { 14 | std::cout << v << " "; 15 | } 16 | std::cout << std::endl; 17 | 18 | std::sort(vec.begin(), vec.end()); 19 | for (auto& v : vec) { 20 | std::cout << v << " "; 21 | } 22 | std::cout << std::endl; 23 | } 24 | -------------------------------------------------------------------------------- /Chapter03/30_polymorphism.cpp: -------------------------------------------------------------------------------- 1 | class Musician { 2 | public: 3 | virtual void play() = 0; 4 | }; 5 | 6 | class Guitarist : public Musician { 7 | public: 8 | void play() override { std::cout << "Play a guitar"; } 9 | }; 10 | 11 | class Pianist : public Musician { 12 | public: 13 | void play() override { std::cout << "Play a piano"; } 14 | }; 15 | 16 | std::vector get_musicians(); 17 | 18 | int main() 19 | { 20 | auto all_musicians = get_musicians(); 21 | for (const auto& m: all_musicians) { 22 | m->play(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Chapter04/ch4_1_macro_func.cpp: -------------------------------------------------------------------------------- 1 | //ch4_1_macro_func.cpp 2 | #include 3 | #define app_max(a,b) ((a)>(b) ? (a):(b)) 4 | int main() { 5 | int a = 5, b = 10; 6 | int c = app_max(a, b); //c=10 7 | float d = 3.2, e = app_max(c, d); //e=10.0f 8 | for (int i = 0; i < 100; ++i) { 9 | int f = app_max(0, std::rand() - RAND_MAX / 2); //is f positive or negative? 10 | //rand() returns an integer in [0,RAND_MAX] 11 | std::cout << "c=" << c << ", e=" << e << ", f=" << f << std::endl; 12 | } 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /Chapter06/1_emails.h: -------------------------------------------------------------------------------- 1 | struct Email { 2 | std::string subject; 3 | std::string body; 4 | std::string from; 5 | std::string when; 6 | }; 7 | ... 8 | // let's suppose a million emails is the max for anyone 9 | int MAX_EMAILS = 1000000; 10 | Email inbox[1000000]; 11 | 12 | std::vector search(const std::string& word) { 13 | std::vector search_results; 14 | for (all-million-emails) { 15 | if (inbox[i].subject.contains(word)) { 16 | search_results.push_back(inbox[i]); 17 | } 18 | } 19 | return search_results; 20 | } 21 | -------------------------------------------------------------------------------- /Chapter03/23_quadratic_solver.cpp: -------------------------------------------------------------------------------- 1 | class QuadraticSolver { 2 | public: 3 | QuadraticSolver() = default; 4 | void set_a(double a); 5 | void set_b(double b); 6 | void set_c(double c); 7 | void find_discriminant(); 8 | double solve(); // solve and return the x 9 | private: 10 | double a_; 11 | double b_; 12 | double c_; 13 | double discriminant_; 14 | }; 15 | 16 | QuadraticSolver solver; 17 | solver.set_a(2); 18 | solver.set_b(5); 19 | solver.set_c(-8); 20 | solver.find_discriminant(); 21 | std::cout << "x is: " << solver.solve() << std::endl; 22 | 23 | -------------------------------------------------------------------------------- /Chapter06/19_graph.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | template 5 | class Graph 6 | { 7 | public: 8 | Graph(); 9 | Graph(const Graph&); 10 | Graph(Graph&&); 11 | Graph& operator=(const Graph&); 12 | Graph& operator=(Graph&&); 13 | ~Graph(); 14 | 15 | public: 16 | void insert_edge(const T& source, const T& target); 17 | void remove_edge(const T& source, const T& target); 18 | 19 | bool connected(const T& source, const T& target); 20 | 21 | private: 22 | std::unordered_map > hashtable_; 23 | }; 24 | -------------------------------------------------------------------------------- /Chapter04/ch4_19_loop_unroolling_traditional.cpp: -------------------------------------------------------------------------------- 1 | //ch4_19_loop_unoolling_convention.cpp 2 | #include 3 | 4 | template 5 | T dotp(int n, const T* a, const T* b) 6 | { 7 | T ret = 0; 8 | for (int i = 0; i < n; ++i) { 9 | ret += a[i] * b[i]; 10 | } 11 | return ret; 12 | } 13 | 14 | int main() 15 | { 16 | float a[5] = { 1, 2, 3, 4, 5 }; 17 | float b[5] = { 6, 7, 8, 9, 10 }; 18 | 19 | std::cout << "dot_product(5,a,b) = " << dotp(5, a, b) << '\n'; //130 20 | std::cout << "dot_product(5,a,a) = " << dotp(5, a, a) << '\n'; //55 21 | } 22 | -------------------------------------------------------------------------------- /Chapter05/5_delete_with_manager.cpp: -------------------------------------------------------------------------------- 1 | template 2 | class ArrayManager { 3 | public: 4 | ArrayManager(T* arr) : arr_{arr} {} 5 | ~ArrayManager() { delete[] arr_; } 6 | 7 | T& operator[](int ix) { return arr_[ix]; } 8 | 9 | T* raw() { return arr_; } 10 | }; 11 | 12 | void print_sorted() { 13 | ArrayManager arr{new short[420]}; 14 | for (int ix = 0; ix < 420; ++ix) { 15 | std::cin >> arr[ix]; 16 | } 17 | strange_sort::sort(arr.raw(), arr.raw() + 420); 18 | for (int ix = 0; ix < 420; ++ix) { 19 | std::cout << arr[ix]; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Chapter03/31_singleton.cpp: -------------------------------------------------------------------------------- 1 | class Warehouse { 2 | public: 3 | static create_instance() { 4 | if (instance_ == nullptr) { 5 | instance_ = new Warehouse(); 6 | } 7 | return instance_; 8 | } 9 | 10 | static remove_instance() { 11 | delete instance_; 12 | instance_ = nullptr; 13 | } 14 | 15 | private: 16 | Warehouse() = default; 17 | 18 | private: 19 | static Warehouse* instance_ = nullptr; 20 | }; 21 | 22 | int main() 23 | { 24 | Warehouse* w = Warehouse::create_instance(); 25 | Product book; 26 | w->add_product(book); 27 | Warehouse::remove_instance(); 28 | } -------------------------------------------------------------------------------- /Chapter13/ch13_tdd_test.cpp: -------------------------------------------------------------------------------- 1 | //ch13_tdd_test.cpp 2 | #include "ch13_tdd_v2.h" 3 | void test_tdd_v1(); 4 | void test_tdd_v2(); 5 | using namespace std; 6 | int main() 7 | { 8 | test_tdd_v1(); 9 | test_tdd_v2(); 10 | return 0; 11 | } 12 | 13 | void test_tdd_v1() 14 | { 15 | Mat x(2, 3); 16 | x.print("int x="); 17 | 18 | Mat y(1, 2); 19 | y.print("float y="); 20 | } 21 | 22 | void test_tdd_v2() 23 | { 24 | Mat x(2, 3, 10); 25 | x.print("int x="); 26 | assert(2 == x.rows()); 27 | assert(3 == x.cols()); 28 | 29 | Mat y(1, 2, 'a'); 30 | y.print("char y="); 31 | 32 | } 33 | -------------------------------------------------------------------------------- /Chapter08/8_thread_pool.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class ThreadPool 5 | { 6 | public: 7 | ThreadPool(int number_of_threads = 1000) { 8 | for (int ix = 0; ix < number_of_threads; ++ix) { 9 | pool_.push(std::thread()); 10 | } 11 | } 12 | 13 | std::thread get_free_thread() { 14 | if (q.empty()) { 15 | throw std::exception("no available thread"); 16 | } 17 | auto t = q.front(); 18 | q.pop(); 19 | return t; 20 | } 21 | 22 | void push_thread(std::thread t) { 23 | q.push(t); 24 | } 25 | 26 | private: 27 | std::queue pool_; 28 | }; 29 | -------------------------------------------------------------------------------- /Chapter04/ch4_15_traits_boost.cpp: -------------------------------------------------------------------------------- 1 | //ch4_15_traits_boost.cpp 2 | #include 3 | #include 4 | 5 | struct X {}; 6 | using namespace std; 7 | int main() 8 | { 9 | cout << boolalpha; 10 | cout << is_void::value << endl; 11 | cout << is_void::value << endl; 12 | cout << is_pointer::value << endl; 13 | cout << is_pointer::value << endl; 14 | cout << is_pointer::value << endl; 15 | cout << is_pointer::value << endl; 16 | cout << is_pointer::value << endl; 17 | cout << is_pointer::value << endl; 18 | cout << is_pointer< nullptr_t>::value << endl; 19 | } 20 | -------------------------------------------------------------------------------- /Chapter10/1_class_user.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | struct Address 7 | { 8 | std::string country; 9 | std::string city; 10 | std::string street; 11 | float latitude; 12 | float longitude; 13 | }; 14 | 15 | class User 16 | { 17 | public: 18 | void User::set_email(const std::string& email) 19 | { 20 | if (!std::regex_match(email, "(\\w+)(\\.|_)?(\\w*)@(\\w+)(\\.(\\w+))+") { 21 | throw std::invalid_argument("Invalid email"); 22 | } 23 | 24 | this->email_ = email; 25 | } 26 | private: 27 | std::string email_; 28 | Address address_; 29 | }; 30 | -------------------------------------------------------------------------------- /Chapter13/ch13_gdb_2.cpp: -------------------------------------------------------------------------------- 1 | //ch13_gdb_2.cpp 2 | #include 3 | 4 | float dotproduct( const float *x, const float *y, const int n); 5 | int main() 6 | { 7 | float sxx,sxy; 8 | float x[] = {1,2,3,4,5}; 9 | float y[] = {0,1,1,1,1}; 10 | 11 | sxx = dotproduct( x, x, 5); 12 | sxy = dotproduct( x, y, 5); 13 | printf( "dot(x,x) = %f\n", sxx ); 14 | printf( "dot(x,y) = %f\n", sxy ); 15 | return 0; 16 | } 17 | 18 | float dotproduct( const float *x, const float *y, const int n ) 19 | { 20 | const float *p = x; 21 | const float *q = x; 22 | float s = 0; 23 | for(int i=0; i b.price; 13 | } 14 | }; 15 | 16 | int main() 17 | { 18 | std::vector products; 19 | products.push_back({5, false, "Product 1"}); 20 | products.push_back({12, true, "Product 2"}); 21 | 22 | std::sort(products.begin(), products.end(), ProductComparator{}); 23 | 24 | std::sort(products.begin(), products.end(), 25 | [](const Product& a, const Product& b) { return a.price > b.price; }) 26 | } 27 | -------------------------------------------------------------------------------- /Chapter10/3_test_set_email.cpp: -------------------------------------------------------------------------------- 1 | void test_set_email() 2 | { 3 | std::string valid_email = "valid@email.com"; 4 | std::string invalid_email = "112%$"; 5 | 6 | User u; 7 | u.set_email(valid_email); 8 | if (u.get_email() == valid_email) { 9 | std::cout << "Success: valid email has been set successfully" << std::endl; 10 | } else { 11 | std::cout << "Fail: valid email has not been set" << std::endl; 12 | } 13 | 14 | try { 15 | u.set_email(invalid_email); 16 | std::cerr << "Fail: invalid email has not been rejected" << std::endl; 17 | } catch (std::exception& e) { 18 | std::cout << "Success: invalid email rejected" << std::endl; 19 | } 20 | } -------------------------------------------------------------------------------- /Chapter10/6_product_hierarchy.h: -------------------------------------------------------------------------------- 1 | class Product 2 | { 3 | public: 4 | // code omitted for brevity 5 | virtual double convert_price(Currency c) { 6 | auto final_price = apply_discount(); 7 | // convert the final_price based on the currency 8 | } 9 | 10 | private: 11 | virtual double apply_discount() { 12 | return getPrice(); // no discount by default 13 | } 14 | 15 | // code omitted for brevity 16 | }; 17 | 18 | class DigitalProduct : public Product 19 | { 20 | public: 21 | // code omitted for brevity 22 | 23 | private: 24 | double apply_discount() override { 25 | return getPrice() * 0.12; 26 | } 27 | 28 | // code omitted for brevity 29 | }; -------------------------------------------------------------------------------- /Chapter14/9_hboxlayout.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char** argv) 4 | { 5 | QApplication app(argc, argv); 6 | 7 | QWidget *window = new QWidget; 8 | QPushButton *btn1 = new QPushButton("Leia"); 9 | QPushButton *btn2 = new QPushButton("Patrick"); 10 | QPushButton *btn3 = new QPushButton("Samo"); 11 | QPushButton *btn4 = new QPushButton("Amat"); 12 | 13 | QHBoxLayout *layout = new QHBoxLayout; 14 | layout->addWidget(btn1); 15 | layout->addWidget(btn2); 16 | layout->addWidget(btn3); 17 | layout->addWidget(btn4); 18 | 19 | window->setLayout(layout); 20 | window->show(); 21 | 22 | return app.exec(); 23 | } -------------------------------------------------------------------------------- /Chapter07/3_count_evens_functional.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using IntMatrix = std::vector>; 6 | 7 | int count_evens(const std::vector& number_line) { 8 | return std::count_if(number_line.begin(), 9 | number_line.end(), [](int num){return num % 2 == 0;}); 10 | } 11 | 12 | std::vector count_all_evens(const IntMatrix& numbers) 13 | { 14 | return numbers | std::ranges::views::transform(count_evens); 15 | } 16 | 17 | int main() 18 | { 19 | IntMatrix m{{1, 2, 3}, {4, 5, 6}}; 20 | for (auto item : count_all_evens(m)) { 21 | std::cout << item << " "; 22 | } 23 | std::cout << std::endl; 24 | } -------------------------------------------------------------------------------- /Chapter13/ch13_tdd_Boost_UTF1.cpp: -------------------------------------------------------------------------------- 1 | // ch13_tdd_Boost_UTF1.cpp 2 | #define BOOST_TEST_MODULE tdd_test 3 | #include 4 | #include "ch13_tdd_v1.h" 5 | 6 | //declare we begin a test suite and name it "my_suite " 7 | BOOST_AUTO_TEST_SUITE(tdd_suite) 8 | 9 | BOOST_AUTO_TEST_CASE(test_case1) { 10 | Mat x(2, 3); 11 | x.print("int x="); 12 | BOOST_TEST(2 == x.rows()); 13 | BOOST_TEST(3 == x.cols()); 14 | 15 | Mat y; 16 | BOOST_TEST(0 == y.rows()); 17 | BOOST_TEST(0 == y.cols()); 18 | 19 | Mat z(1,10); 20 | BOOST_TEST(1 == z.rows()); 21 | BOOST_TEST(10 == z.cols()); 22 | } 23 | BOOST_AUTO_TEST_SUITE_END() //declare we end test suite 24 | 25 | -------------------------------------------------------------------------------- /Chapter04/ch4_7_variadic_my_min.cpp: -------------------------------------------------------------------------------- 1 | //ch4_7_variadic_my_min.cpp 2 | //this program is tested on g++ (Ubuntu/Linaro 7.3.0-27ubuntu1~18.04) 7.3.0 3 | //it may have compile errors for other platforms 4 | #include 5 | #include 6 | 7 | double my_min(double n) 8 | { 9 | return n; 10 | } 11 | 12 | template 13 | double my_min(double n, Args... args) 14 | { 15 | return fmin(n, my_min(args...)); 16 | } 17 | 18 | using namespace std; 19 | int main() { 20 | 21 | double x1 = my_min(2); 22 | double x2 = my_min(2, 3); 23 | double x3 = my_min(2, 3, 4, 5, 4.7,5.6, 9.9, 0.1); 24 | cout << "x1=" << x1 << ", x2=" << x2 << ", x3=" << x3 << endl; 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /Chapter13/ch13_tdd_v1.h: -------------------------------------------------------------------------------- 1 | //ch13_tdd_v1.h 2 | #ifndef __CH13_TDD_V1__ 3 | #define __CH13_TDD_V1__ 4 | #include 5 | #include 6 | template< class T> 7 | class Mat { 8 | public: 9 | Mat(const uint32_t m=0, const uint32_t n=0); 10 | Mat(const Mat &rhs) = delete; 11 | ~Mat(); 12 | 13 | Mat& operator = (const Mat &x) = delete; 14 | 15 | uint32_t rows() { return m_rows; } 16 | uint32_t cols() { return m_cols; } 17 | void print(const char* str) const; 18 | 19 | private: 20 | void creatBuf(); 21 | void deleteBuf(); 22 | uint32_t m_rows; //# of rows 23 | uint32_t m_cols; //# of cols 24 | T* m_buf; 25 | }; 26 | 27 | #include "ch13_tdd_v1.cpp" 28 | 29 | #endif 30 | 31 | -------------------------------------------------------------------------------- /Chapter09/2_double_checked_guard.cpp: -------------------------------------------------------------------------------- 1 | static std::shared_ptr get_instance() 2 | { 3 | 4 | } 5 | 6 | namespace Db { 7 | 8 | class ConnectionManager 9 | { 10 | public: 11 | static std::shared_ptr get_instance() 12 | { 13 | if (instance_ == nullptr) { 14 | // mutex_ is declared in the private section 15 | std::lock_guard lg{mutex_}; 16 | if (instance_ == nullptr) { // double-checking 17 | instance_.reset(new ConnectionManager()); 18 | } 19 | } 20 | return instance_; 21 | } 22 | 23 | // Database connection related code omitted 24 | private: 25 | static std::shared_ptr instance_{nullptr}; 26 | }; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /Chapter04/ch4_5_class_template_implicit_inst_B.cpp: -------------------------------------------------------------------------------- 1 | //file ch4_5_class_template_implicit_inst_B.cpp 2 | #include "ch4_5_class_template_implicit_inst.h" 3 | int main() 4 | { 5 | X xi; //implicit instantiation generates class X, then create object xi 6 | xi.f(); //and generates function X::f(), but not X::g() 7 | 8 | typedef void (X::*TFuncPtr)(); 9 | TFuncPtr pf = &X::f; 10 | TFuncPtr pg = &X::g; 11 | TFuncPtr ph = &X::h; 12 | std::cout << pf << ", " << pf << std::endl; 13 | 14 | X xf; //implicit instantiation generates class X, then create object xf 15 | xf.g(); //and generates function X::g(), but not X::f() 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /Chapter12/1_socket.cpp: -------------------------------------------------------------------------------- 1 | int s = socket(AF_INET, SOCK_STREAM, 0); 2 | 3 | struct sockaddr_in server; 4 | server.sin_family = AF_INET; 5 | server.sin_port = htons(port); 6 | server.sin_addr.s_addr = INADDR_ANY; 7 | 8 | bind(s, (struct sockaddr*)&server, sizeof(server)); 9 | 10 | listen(s, 5); 11 | 12 | struct sockaddr_in client; 13 | int addrlen; 14 | int new_socket = accept(s, (struct sockaddr_in*)&client, &addrlen); 15 | // use the new_socket 16 | 17 | char buffer[BUFFER_MAX_SIZE]; // define BUFFER_MAX_SIZE based on the specifics of the server 18 | recv(new_socket, buffer, sizeof(buffer), 0); 19 | // now the buffer contains received data 20 | 21 | char msg[] = "From server with love"; 22 | send(new_socket, msg, sizeof(msg), 0); -------------------------------------------------------------------------------- /Chapter15/2_set_examples.cpp: -------------------------------------------------------------------------------- 1 | void CalculationMachine::setExamples(const Examples& examples) 2 | { 3 | int sum_count{0}; 4 | int sub_count{0}; 5 | int mul_count{0}; 6 | int div_count{0}; 7 | for (const auto& example : Examples) { 8 | if (CalculationMachine.sum(example.input1, example.input2) == example.output) { 9 | ++sum_count; 10 | } 11 | if (CalculationMachine.subtract(example.input1, example.input2) == example.output) { 12 | ++sub_count; 13 | } 14 | // the same for multiply() and divide() 15 | } 16 | 17 | // the function that has the maximum number of correct output results 18 | // becomes the main function for called by calculate() 19 | // fptr_ is assigned the winner arithmetic function 20 | } -------------------------------------------------------------------------------- /Chapter04/ch4_5_class_template_implicit_inst_D.cpp: -------------------------------------------------------------------------------- 1 | //file ch4_5_class_template_implicit_inst_D.cpp 2 | #include "ch4_5_class_template_implicit_inst.h" 3 | int main() 4 | { 5 | X *p_xi; //instantiation of class X is not required, since p_xi is pointer object 6 | p_xi = new X(); 7 | p_xi->f(); //implicit instantiation of X and X::f() occurs here, but not X::g() 8 | 9 | X *p_xf; //instantiation of class X is not required, since p_xf is pointer object 10 | p_xf = new X(); 11 | p_xf->f(); //implicit instantiation of X and X::f() occurs here 12 | p_xf->g(); //implicit instantiation of X::g() occurs here 13 | 14 | delete p_xi; 15 | delete p_xf; 16 | return 0; 17 | } -------------------------------------------------------------------------------- /Chapter07/1_count_all_evens.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using IntMatrix = std::vector>; 5 | 6 | std::vector count_all_evens(const IntMatrix& numbers) 7 | { 8 | int even{0}; 9 | std::vector even_numbers_count; 10 | for (const auto& number_line: numbers) { 11 | for (const auto& number: number_line) { 12 | if (number % 2 == 0) { 13 | ++even; 14 | } 15 | } 16 | even_numbers_count.push_back(even); 17 | even = 0; 18 | } 19 | return even_numbers_count; 20 | } 21 | 22 | int main() 23 | { 24 | IntMatrix m{{1, 2, 3}, {4, 5, 6}}; 25 | for (auto item : count_all_evens(m)) { 26 | std::cout << item << " "; 27 | } 28 | std::cout << std::endl; 29 | } -------------------------------------------------------------------------------- /Chapter07/8_pure_function.cpp: -------------------------------------------------------------------------------- 1 | struct User 2 | { 3 | int age; 4 | string name; 5 | string phone_number; 6 | string email; 7 | }; 8 | 9 | void update_age(User& u) 10 | { 11 | u.age = u.age + 1; 12 | } 13 | 14 | User pure_update_age(const User& u) // cannot modify the input argument 15 | { 16 | User tmp{u}; 17 | tmp.age = tmp.age + 1; 18 | return tmp; 19 | } 20 | 21 | User pure_update_age(User u) // u is the copy of the passed object 22 | { 23 | u.age = u.age + 1; 24 | return u; 25 | } 26 | 27 | int main() 28 | { 29 | User john{.age{21}, .name{"John"}}; 30 | 31 | auto updated{pure_update_age(john)}; 32 | std::cout << updated.age; // prints 22 33 | 34 | updated = pure_update_age(john); 35 | std::cout << updated.age; // prints 22 36 | } -------------------------------------------------------------------------------- /Chapter03/10_class.h: -------------------------------------------------------------------------------- 1 | class Product { 2 | public: 3 | Product() = default; // default constructor 4 | Product(const Product&); // copy constructor 5 | Product(Product&&); // move constructor 6 | 7 | Product& operator=(const Product&) = default; 8 | Product& operator=(Product&&) = default; 9 | // destructor is not declared, should be generated by the compiler 10 | public: 11 | void set_name(const std::string&); 12 | std::string name() const; 13 | void set_availability(bool); 14 | bool available() const; 15 | // code omitted for brevity 16 | 17 | private: 18 | std::string name_; 19 | double price_; 20 | int rating_; 21 | bool available_; 22 | }; 23 | 24 | std::ostream& operator<<(std::ostream&, const Product&); 25 | std::istream& operator>>(std::istream&, Product&); -------------------------------------------------------------------------------- /Chapter09/7_lockfree_stack.cpp: -------------------------------------------------------------------------------- 1 | template 2 | class lock_free_stack 3 | { 4 | private: 5 | struct node { 6 | T data; 7 | node* next; 8 | node(const T& d) : data(d) {} 9 | } 10 | 11 | public: 12 | void push(const T& data) 13 | { 14 | node* new_elem = new node(data); 15 | new_elem->next = head_.load(); 16 | while (!head_.compare_exchange_weak(new_elem->next, new_elem)); 17 | } 18 | 19 | void pop(T& popped_element) 20 | { 21 | node* old_head = head_.load(); 22 | while (!head_.compare_exchange_weak(old_head, old_head->next)); 23 | popped_element = old_head->data; 24 | } 25 | 26 | private: 27 | std::atomic head_; 28 | node* head_; 29 | // the rest of the body is omitted for brevity 30 | }; 31 | -------------------------------------------------------------------------------- /Chapter15/1_example.h: -------------------------------------------------------------------------------- 1 | struct Example 2 | { 3 | int input1; 4 | int input 2; 5 | int output; 6 | }; 7 | 8 | class CalculationMachine 9 | { 10 | public: 11 | using Examples = std::vector; 12 | // pass calculation examples through the setExamples() 13 | void setExamples(const Examples& examples); 14 | 15 | // the main function of interest 16 | // returns the result of the calculation 17 | int calculate(int a, int b); 18 | 19 | private: 20 | // this function pointer will point to 21 | // one of the arithmetic functions below 22 | int (*fptr_)(int, int) = nullptr; 23 | 24 | private: 25 | // set of arithmetic functions 26 | static int sum(int, int); 27 | static int subtract(int, int); 28 | static int multiply(int, int); 29 | static int divide(int, int); 30 | }; -------------------------------------------------------------------------------- /Chapter07/2_count_all_evens_short.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using IntMatrix = std::vector>; 5 | 6 | int count_evens(const std::vector& number_line) { 7 | return std::count_if(number_line.begin(), 8 | number_line.end(), [](int num){return num % 2 == 0;}); 9 | } 10 | 11 | std::vector count_all_evens(const IntMatrix& numbers) 12 | { 13 | std::vector even_numbers_count; 14 | for (const auto& number_line: numbers) { 15 | even_numbers_count.push_back(count_evens(number_line)); 16 | } 17 | return even_numbers_count; 18 | } 19 | 20 | int main() 21 | { 22 | IntMatrix m{{1, 2, 3}, {4, 5, 6}}; 23 | for (auto item : count_all_evens(m)) { 24 | std::cout << item << " "; 25 | } 26 | std::cout << std::endl; 27 | } -------------------------------------------------------------------------------- /Chapter04/ch4_20_loop_unroolling_metaprogramming.cpp: -------------------------------------------------------------------------------- 1 | //ch4_20_loop_unroolling_metaprogramming.cpp 2 | #include 3 | 4 | //primary template 5 | template 6 | class dotp { 7 | public: 8 | static T result(T* a, T* b) { 9 | return *a * *b + dotp::result(a + 1, b + 1); 10 | } 11 | }; 12 | 13 | // partial specialization for end criteria 14 | template 15 | class dotp<1, T> { 16 | public: 17 | static T result(T* a, T* b) { 18 | return *a * *b; 19 | } 20 | }; 21 | 22 | int main() 23 | { 24 | float a[5] = { 1, 2, 3, 4, 5 }; 25 | float b[5] = { 6, 7, 8, 9, 10 }; 26 | 27 | std::cout << "dot_product(5,a,b) = " << dotp<5, float>::result( a, b) << '\n'; //130 28 | std::cout << "dot_product(5,a,a) = " << dotp<5,float>::result( a, a) << '\n'; //55 29 | } 30 | -------------------------------------------------------------------------------- /Chapter04/ch4_11_template_template_param.cpp: -------------------------------------------------------------------------------- 1 | //ch4_11_template_template_param.cpp (courtesy: https://stackoverflow.com) 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define __PRETTY_FUNCTION__ __FUNCSIG__ 8 | 9 | using namespace std; 10 | template class X, class... Args> 11 | std::ostream& operator <<(std::ostream& os, const X& objs) { 12 | os << __PRETTY_FUNCTION__ << ":" << endl; 13 | for (auto const& obj : objs) 14 | os << obj << ' '; 15 | return os; 16 | } 17 | 18 | int main() { 19 | vector x{ 3.14f, 4.2f, 7.9f, 8.08f }; 20 | cout << x << '\n'; 21 | 22 | list y{ 'E', 'F', 'G', 'H', 'I' }; 23 | cout << y << '\n'; 24 | 25 | deque z{ 10, 11, 303, 404 }; 26 | cout << z << '\n'; 27 | return 0; 28 | } -------------------------------------------------------------------------------- /Chapter03/8_mimicking_class.cpp: -------------------------------------------------------------------------------- 1 | struct Product { 2 | std::string name; 3 | double price; 4 | int rating; 5 | bool available; 6 | }; 7 | 8 | void initialize(Product* p) { 9 | p->price = 0.0; 10 | p->rating = 0; 11 | p->available = false; 12 | } 13 | 14 | void set_name(Product* p, const std::string& name) { 15 | p->name = name; 16 | } 17 | 18 | std::string get_name(Product* p) { 19 | return p->name; 20 | } 21 | 22 | void set_price(Product* p, double price) { 23 | if (price < 0 || price > 9999.42) return; 24 | p->price = price; 25 | } 26 | 27 | double get_price(Product* p) { 28 | return p->price; 29 | } 30 | 31 | int main() { 32 | Product cpp_book; 33 | initialize(&cpp_book); 34 | set_name(&cpp_book, "Mastering C++ Programming"); 35 | std::cout << "Book title is: " << get_name(&cpp_book); 36 | // ... 37 | } -------------------------------------------------------------------------------- /Chapter11/2_reader.h: -------------------------------------------------------------------------------- 1 | #include "1_character_unit.h" 2 | 3 | class Reader : public CharacterUnit 4 | { 5 | public: 6 | Reader(); 7 | Reader(const Reader&) = delete; 8 | Reader& operator=(const Reader&) = delete; 9 | 10 | public: 11 | void attack(const CharacterUnit& attacker) override { 12 | decrease_life_points_by_(attacker.get_power()); 13 | } 14 | 15 | void destroy() override { 16 | // we will leave this empty for now 17 | } 18 | 19 | int get_life_points() const override { 20 | return life_points_; 21 | } 22 | 23 | int get_power() const override { 24 | return power_; 25 | } 26 | 27 | private: 28 | void decrease_life_points_(int num) { 29 | life_points_ -= num; 30 | if (life_points_ <= 0) { 31 | destroy(); 32 | } 33 | } 34 | 35 | private: 36 | int life_points_; 37 | int power_; 38 | }; -------------------------------------------------------------------------------- /Chapter03/16_warehouse.cpp: -------------------------------------------------------------------------------- 1 | class Product; 2 | 3 | class Warehouse { 4 | public: 5 | Warehouse() 6 | : size_{0}, capacity_{1000}, products_{nullptr} 7 | { 8 | products_ = new Products[capacity_]; 9 | } 10 | 11 | ~Warehouse() { 12 | delete [] products_; 13 | } 14 | 15 | public: 16 | void add_product(const Product& p) { 17 | if (size_ == capacity_) { /* resize */ } 18 | products_[size_++] = p; 19 | } 20 | // other functions omitted for brevity 21 | 22 | private: 23 | int size_; 24 | int capacity_; 25 | Product* products_; 26 | }; 27 | 28 | int main() { 29 | Warehouse w1; 30 | Product book; 31 | Product apple; 32 | // ...assign values to products (omitted for brevity) 33 | w1.add_product(book); 34 | Warehouse w2 = w1; // copy 35 | w2.add_product(apple); 36 | // something somewhere went wrong... 37 | } -------------------------------------------------------------------------------- /Chapter10/5_user_with_payment_options.h: -------------------------------------------------------------------------------- 1 | class User 2 | { 3 | public: 4 | // code omitted for brevity 5 | using PaymentOptionList = std::vector; 6 | PaymentOption get_primary_payment_option() const { 7 | return primary_payment_option_; 8 | } 9 | 10 | PaymentOptionList get_payment_options() const { 11 | return payment_options_; 12 | } 13 | 14 | void add_payment_option(const PaymentOption& po, bool is_primary) { 15 | if (is_primary) { 16 | // moving current primary option to non-primaries 17 | add_payment_option(primary_payment_option_, false); 18 | primary_payment_option_ = po; 19 | return; 20 | } 21 | payment_options_.push_back(po); 22 | } 23 | 24 | private: 25 | // code omitted for brevity 26 | PaymentOption primary_payment_option_; 27 | PaymentOptionList payment_options_; 28 | }; -------------------------------------------------------------------------------- /Chapter11/5_barrack.h: -------------------------------------------------------------------------------- 1 | class IBuilding 2 | { 3 | public: 4 | virtual void attack(const CharacterUnit&) = 0; 5 | virtual void destroy() = 0; 6 | virtual void build(CharacterUnit*) = 0; 7 | virtual int get_life_points() const = 0; 8 | }; 9 | 10 | class Barrack : public IBuilding 11 | { 12 | public: 13 | void attack(const CharacterUnit& attacker) override { 14 | decrease_life_points_(attacker.get_power()); 15 | } 16 | 17 | void destroy() override { 18 | // we will leave this empty for now 19 | } 20 | 21 | void build(CharacterUnit* builder) override { 22 | // we will lock the builder later 23 | construction 24 | } 25 | 26 | int get_life_points() const override { 27 | return life_points_; 28 | } 29 | 30 | private: 31 | int life_points_; 32 | int capacity_; 33 | std::chrono::duration construction_duration_; 34 | }; -------------------------------------------------------------------------------- /Chapter03/27_rectangle_square.cpp: -------------------------------------------------------------------------------- 1 | class Rectangle { 2 | public: 3 | // argument checks omitted for brevity 4 | void set_width(int w) { width_ = w; } 5 | void set_height(int h) { height_ = h; } 6 | int area() const { return width_ * height_; } 7 | private: 8 | int width_; 9 | int height_; 10 | }; 11 | 12 | class Square : public Rectangle { 13 | public: 14 | void set_side(int side) { 15 | set_width(side); 16 | set_height(side); 17 | } 18 | 19 | int area() { 20 | area_ = Rectangle::area(); 21 | return area_; 22 | } 23 | private: 24 | int area_; 25 | }; 26 | 27 | void make_big_rectangle(Rectangle& ref) { 28 | ref->set_width(870); 29 | ref->set_height(940); 30 | } 31 | 32 | int main() { 33 | Rectangle rect; 34 | make_big_rectangle(rect); 35 | Square sq; 36 | // Square is a Rectangle 37 | make_big_rectangle(sq); 38 | } -------------------------------------------------------------------------------- /Chapter04/ch4_16_traits_limits.cpp: -------------------------------------------------------------------------------- 1 | //ch4_16_traits_limits.cpp 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | int main() 7 | { 8 | cout << "is_signed(char): " << numeric_limits::is_signed << endl; 9 | cout << "is_specialized(long double): " 10 | << numeric_limits::is_specialized << endl; 11 | cout << "is_specialized(std::string): " 12 | << numeric_limits::is_specialized << endl; 13 | cout << "int: is_specialized=" << numeric_limits::is_specialized; 14 | cout << ", min=" << numeric_limits::min(); 15 | cout << ", max=" << numeric_limits::max() << endl; 16 | cout << "uint32_t: is_specialized=" << numeric_limits::is_specialized; 17 | cout << ", min=" << numeric_limits::min(); 18 | cout << ", max=" << numeric_limits::max() << endl; 19 | return 0; 20 | } -------------------------------------------------------------------------------- /Chapter13/ch13_tdd_v2.h: -------------------------------------------------------------------------------- 1 | //ch13_tdd_v1.h 2 | #ifndef __CH13_TDD_V2__ 3 | #define __CH13_TDD_V2__ 4 | #include 5 | #include 6 | template< class T> 7 | class Mat { 8 | public: 9 | Mat(const uint32_t m=0, const uint32_t n=0); 10 | Mat(const uint32_t m, const uint32_t n, const T initVal); 11 | Mat(const Mat &rhs) = delete; 12 | ~Mat(); 13 | 14 | Mat& operator = (const Mat &x) = delete; 15 | 16 | uint32_t rows() { return m_rows; } 17 | uint32_t cols() { return m_cols; } 18 | uint32_t numel() { return m_rows * m_cols;} 19 | uint32_t empty() { return 0==m_rows || 0==m_cols; } 20 | 21 | void print(const char* str) const; 22 | 23 | private: 24 | void creatBuf(); 25 | void deleteBuf(); 26 | uint32_t m_rows; //# of rows 27 | uint32_t m_cols; //# of cols 28 | T* m_buf; 29 | }; 30 | 31 | #include "ch13_tdd_v2.cpp" 32 | 33 | #endif 34 | 35 | -------------------------------------------------------------------------------- /Chapter13/ch13_unit_test10.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE MyTest 2 | #include 3 | 4 | float div1(float num, float den) { return num / den; } 5 | float div2(float num, float den) { 6 | if (den == 0) { return NAN;} 7 | return num / den; 8 | } 9 | 10 | BOOST_AUTO_TEST_CASE(test1) 11 | { 12 | //boost continues on error tools 13 | BOOST_CHECK(div1(2, 1) == 2); 14 | BOOST_CHECK(div1(0, 2) == 0); 15 | if (div1(2, 0) != INFINITY) 16 | BOOST_ERROR("Ouch..."); 17 | 18 | BOOST_CHECK_MESSAGE( div1(2, 1) == 4, 19 | "add(..) result: " << div1(2, 1)); 20 | 21 | BOOST_CHECK_EQUAL(div1(2, 0), INFINITY); 22 | 23 | //throw on error tools 24 | BOOST_REQUIRE(div1(2, 1) == 4); // #2 throws on error 25 | if ( div1(1, 0) != NAN) 26 | BOOST_FAIL("Ouch..."); // #4 throws on error 27 | if ( div1(1, 0) != INFINITY) throw "Ouch..."; // #5 throws on error 28 | 29 | } -------------------------------------------------------------------------------- /Chapter04/ch4_10_none_type_template_param2.cpp: -------------------------------------------------------------------------------- 1 | //ch4_10_none_type_template_param2.cpp 2 | #include 3 | template 4 | void foo() { 5 | std::cout << msg << std::endl; 6 | } 7 | 8 | // need to have external linkage 9 | extern const char str1[] = "Test 1"; 10 | constexpr char str2[] = "Test 2"; 11 | extern const char* str3 = "Test 3"; 12 | int main() 13 | { 14 | foo(); 15 | foo(); 16 | //foo(); //error: 'str3' is not a valid template argument because 'str3' is a variable, not the address of a variable 17 | 18 | //const char str4[] = "Test 4"; 19 | //constexpr char str5[] = "Test 5"; 20 | //foo(); //error: 'str4' is not a valid template argument of type 'const char*' because 'str4' has no linkage 21 | //foo(); // error: 'str5' is not a valid template argument of type 'const char*' because 'str5' has no linkage 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /Chapter09/5_thread_safe_stack.cpp: -------------------------------------------------------------------------------- 1 | template 2 | class safe_stack 3 | { 4 | public: 5 | safe_stack() {} 6 | safe_stack(const safe_stack& other) { 7 | std::lock_guard lock(other.mutex_); 8 | wrappee_ = other.wrappee_; 9 | } 10 | void push(T value) { 11 | std::lock_guard lock(mutex_); 12 | // note how we std::move the value 13 | wrappee_.push(std::move(value)); 14 | } 15 | void pop() { 16 | std::lock_guard lock(mutex_); 17 | if (wrappee_.empty()) { 18 | throw std::exception("The stack is empty"); 19 | } 20 | std::shared_ptr top_element{std::make_shared(std::move(wrappee_.top()))}; 21 | wrappee_.pop(); 22 | return top_element; 23 | } 24 | 25 | bool empty() const { return wrappee_.empty(); } 26 | 27 | private: 28 | std::stack wrappee_; 29 | mutable std::mutex mutex_; 30 | }; 31 | -------------------------------------------------------------------------------- /Chapter03/11_class_compilers_perspective.h: -------------------------------------------------------------------------------- 1 | struct Product { 2 | std::string name_; 3 | bool available_; 4 | double price_; 5 | int rating_; 6 | }; 7 | 8 | void Product_constructor(Product&); // we forced the compiler to generate the default constructor 9 | void Product_copy_constructor(Product& this, const Product&); 10 | void Product_move_constructor(Product& this, Product&&); 11 | Product& operator=(Product& this, const Product&); // default implementation 12 | Product& operator=(Product& this, Product&&); // default implementation 13 | 14 | void Product_set_name(const std::string&); 15 | std::string Product_name(const Product& this); // takes const because the method was declared const 16 | void Product_set_availability(Product& this, bool b); 17 | bool Product_availability(const Product& this); 18 | 19 | std::ostream& operator<<(std::ostream&, const Product&); 20 | std::istream& operator>>(std::istream&, Product&); -------------------------------------------------------------------------------- /Chapter04/ch4_13_template_template_argument.cpp: -------------------------------------------------------------------------------- 1 | //ch4_12_template_template_argument.cpp 2 | 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | //primary class template X with template type parameters 8 | template 9 | class X { 10 | public: 11 | T a; 12 | U b; 13 | }; 14 | 15 | //partially specialization of class template X 16 | template 17 | class X { 18 | public: 19 | int a; 20 | U b; 21 | }; 22 | 23 | //primary class template Y with template template parameter 24 | template class V> 25 | class Y { 26 | public: 27 | V i; 28 | V j; 29 | }; 30 | 31 | Y c; 32 | 33 | int main() { 34 | cout << typeid(c.i.a).name() << endl; //short 35 | cout << typeid(c.i.b).name() << endl; //char 36 | cout << typeid(c.j.a).name() << endl; //char 37 | cout << typeid(c.j.b).name() << endl; //char 38 | return 0; 39 | } -------------------------------------------------------------------------------- /Chapter03/29_protected_inheritance.h: -------------------------------------------------------------------------------- 1 | class Vector { 2 | public: 3 | Vector(); 4 | Vector(const Vector&); 5 | Vector(Vector&&); 6 | Vector& operator=(const Vector&); 7 | Vector& operator=(Vector&&); 8 | ~Vector(); 9 | 10 | public: 11 | void push_back(int value); 12 | void insert(int index, int value); 13 | void remove(int index); 14 | int operator[](int index); 15 | int size() const; 16 | int capacity() const; 17 | 18 | private: 19 | int size_; 20 | int capacity_; 21 | int* array_; 22 | }; 23 | 24 | class Stack : protected Vector { 25 | public: 26 | // constructors, assignment operators and the destructor are omitted for brevity 27 | void push(int value) { 28 | push_back(value); 29 | } 30 | int pop() { 31 | int value{this[size() - 1]}; 32 | remove(size() - 1); 33 | return value; 34 | } 35 | }; 36 | 37 | class AdvancedStack : public Stack { 38 | // can use the Vector 39 | }; 40 | -------------------------------------------------------------------------------- /Chapter04/ch4_14_default_template_arguments.cpp: -------------------------------------------------------------------------------- 1 | //ch4_14_default_template_arguments.cpp 2 | #include 3 | #include 4 | template class X; 5 | template class X; 6 | 7 | template class X { 8 | public: 9 | T1 a; 10 | T2 b; 11 | }; 12 | 13 | template class Y; 14 | template class Y 15 | { public: 16 | T a; 17 | }; 18 | 19 | int main() { 20 | X x1; // 21 | Xx2; // 22 | X<>x3; // 23 | X x4; // 24 | std::cout << typeid(x1.a).name() << ", " << typeid(x1.b).name() << std::endl; 25 | std::cout << typeid(x2.a).name() << ", " << typeid(x2.b).name() << std::endl; 26 | std::cout << typeid(x3.a).name() << ", " << typeid(x3.b).name() << std::endl; 27 | std::cout << typeid(x4.a).name() << ", " << typeid(x4.b).name() << std::endl; 28 | return 0; 29 | } -------------------------------------------------------------------------------- /Chapter11/8_prototype.h: -------------------------------------------------------------------------------- 1 | class CharacterUnit 2 | { 3 | public: 4 | CharacterUnit() {} 5 | CharacterUnit& operator=(const CharacterUnit&) = delete; 6 | virtual ~Character() {} 7 | 8 | virtual CharacterUnit* clone() = 0; 9 | 10 | public: 11 | void move(const Point& to) { 12 | // the graphics-specific implementation 13 | } 14 | virtual void attack(const CharacterUnit&) = 0; 15 | virtual void destroy() = 0; 16 | 17 | int get_power() const { return power_; } 18 | int get_life_points() const { return life_points_; } 19 | 20 | private: 21 | CharacterUnit(const CharacterUnit& other) { 22 | life_points_ = other.life_points_; 23 | power_ = other.power_; 24 | } 25 | 26 | private: 27 | int life_points_; 28 | int power_; 29 | }; 30 | 31 | class Reader : public CharacterUnit 32 | { 33 | public: 34 | Reader* clone() override { 35 | return new Reader(*this); 36 | } 37 | 38 | // code omitted for brevity 39 | }; -------------------------------------------------------------------------------- /Chapter13/ch13_unit_test1.cpp: -------------------------------------------------------------------------------- 1 | //ch13_unit_test1.cpp 2 | #define BOOST_TEST_MODULE my_test //item 1, "my_test" is module name 3 | #include //item 2, header-only 4 | 5 | //declare we begin a test suite and name it "my_suite " 6 | BOOST_AUTO_TEST_SUITE(my_suite) 7 | 8 | //item 3, add a test case into test suit, here we choose BOOST_AUTO_TEST_CASE and name it "test_case1" 9 | BOOST_AUTO_TEST_CASE(test_case1) { 10 | char x = 'a'; 11 | BOOST_TEST(x); //item 4, checks if c is non-zero 12 | BOOST_TEST(x == 'a'); //item 4, checks if c has value 'a' 13 | BOOST_TEST(x == 'b'); //item 4, checks if c has value 'b' 14 | } 15 | 16 | //item 3, add the 2nd test case 17 | BOOST_AUTO_TEST_CASE(test_case2) 18 | { 19 | BOOST_TEST(true); 20 | } 21 | 22 | //item 3, add the 3rd test case 23 | BOOST_AUTO_TEST_CASE(test_case3) 24 | { 25 | BOOST_TEST(false); 26 | } 27 | 28 | BOOST_AUTO_TEST_SUITE_END() //declare we end test suite -------------------------------------------------------------------------------- /Chapter04/ch4_3_func_template_specialization.cpp: -------------------------------------------------------------------------------- 1 | //ch4_3_func_template_specialization.cpp 2 | #include 3 | #include 4 | 5 | //primary template 6 | template T app_max(T a, T b) { return (a>b ? a : b); } 7 | 8 | //explicit specialization for T=std::string, note instead of comparing a and b, we only comparing a[0] and //b[0] which means the behavior app_max() is specialized. 9 | template <> std::string app_max(std::string a, std::string b) { return (a[0]>b[0] ? a : b); } 10 | 11 | int main() { 12 | std::string a = "abc", b = "efg"; 13 | std::cout << app_max(5, 6) << std::endl; //calls app_max(int,int) 14 | std::cout << app_max(a, b) << std::endl; //calls specialized 15 | //app_max(std::string,std::string) 16 | //question: what will happen if you un-comment the following two lines? 17 | char *x = "abc", *y="efg"; 18 | std::cout << app_max(x, y) << std::endl; //call whom? 19 | return 0; 20 | } -------------------------------------------------------------------------------- /Chapter10/7_interfaces.h: -------------------------------------------------------------------------------- 1 | #include "6_product_hierarchy.h" 2 | 3 | class IShippable 4 | { 5 | public: 6 | virtual void ship() = 0; 7 | }; 8 | 9 | class IReplaceable 10 | { 11 | public: 12 | virtual void replace() = 0; 13 | }; 14 | 15 | class IExpirable 16 | { 17 | public: 18 | virtual void expire() = 0; 19 | }; 20 | 21 | class PhysicalProduct : public Product {}; 22 | 23 | // The book is not expiring 24 | class Book : public PhysicalProduct, public IShippable, public IReplaceable 25 | { 26 | }; 27 | 28 | // A house is not shipped, not replaced, but it can expire 29 | // if the landlord decided to put it on sell till a specified date 30 | class House : public PhysicalProduct, public IExpirable 31 | { 32 | }; 33 | 34 | class DigitalProduct : public Product {}; 35 | 36 | // An audio book is not shippable and it's not expiring. 37 | // But we implement IReplaceable in case we send a wrong file to the user. 38 | class AudioBook : public DigitalProduct, public IReplaceable 39 | { 40 | }; -------------------------------------------------------------------------------- /Chapter06/3_vector_puhs_back.h: -------------------------------------------------------------------------------- 1 | template 2 | class Vector 3 | { 4 | public: 5 | // code omitted for brevity 6 | void push_back(const T& item) 7 | { 8 | if (size_ == capacity_) { 9 | capacity_ *= 2; // increase the capacity of the vector twice 10 | T* temp_buffer = new T[capacity_]; 11 | // copy elements of the old into the new 12 | for (int ix = 0; ix < size_; ++ix) { 13 | temp_buffer[ix] = buffer_[ix]; 14 | } 15 | delete [] buffer_; // free the old array 16 | buffer_ = temp_buffer; // point the buffer_ to the new array 17 | } 18 | buffer_[size_++] = item; 19 | } 20 | 21 | void push_front(const T& item) 22 | { 23 | if (size_ == capacity_) { 24 | // resizing code omitted for brevity 25 | } 26 | // shifting all the elements to the right 27 | for (int ix = size_ - 1; ix > 0; --ix) { 28 | buffer_[ix] = buffer[ix - 1]; 29 | } 30 | // adding item at the front 31 | buffer_[0] = item; 32 | size_++; 33 | } 34 | 35 | }; 36 | -------------------------------------------------------------------------------- /Chapter13/ch13_tdd_Boost_UTF2.cpp: -------------------------------------------------------------------------------- 1 | // ch13_tdd_Boost_UTF2.cpp 2 | #define BOOST_TEST_MODULE tdd_test 3 | #include 4 | #include "ch13_tdd_v2.h" 5 | 6 | //declare we begin a test suite and name it "my_suite " 7 | BOOST_AUTO_TEST_SUITE(tdd_suite) 8 | 9 | //add the 1st test case 10 | BOOST_AUTO_TEST_CASE(test_case1) { 11 | Mat x(2, 3); 12 | x.print("int x="); 13 | BOOST_TEST(2 == x.rows()); 14 | BOOST_TEST(3 == x.cols()); 15 | 16 | Mat y; 17 | BOOST_TEST(0 == y.rows()); 18 | BOOST_TEST(0 == y.cols()); 19 | 20 | Mat z(1, 10); 21 | BOOST_TEST(1 == z.rows()); 22 | BOOST_TEST(10 == z.cols()); 23 | } 24 | 25 | //add the 2nd test case 26 | BOOST_AUTO_TEST_CASE(test_case2) 27 | { 28 | Mat x(2, 3, 10); 29 | x.print("int x="); 30 | BOOST_TEST( 6 == x.numel() ); 31 | BOOST_TEST( false == x.empty() ); 32 | 33 | Mat y; 34 | BOOST_TEST( 0 == y.numel() ); 35 | BOOST_TEST( x.empty() ); //bug x --> y 36 | } 37 | 38 | BOOST_AUTO_TEST_SUITE_END() //declare we end test suite 39 | 40 | -------------------------------------------------------------------------------- /Chapter04/ch4_18_factorial_metaprogramming.cpp: -------------------------------------------------------------------------------- 1 | //ch4_18_factorial_metaprogramming.cpp 2 | #include 3 | //define a primary template with non-type parameters (parameters (here n) are not data types) 4 | template struct fact { 5 | const static uint32_t value = n * fact::value; 6 | //use next line of you compiler does not support "declare and initialize a constant static int type 7 | //member inside the class declaration" 8 | //enum { value = n * fact::value }; 9 | }; 10 | 11 | template <> struct fact<0> { //fully specialized template for n as 0 12 | const static uint32_t value = 1; 13 | //enum { value = 1 }; 14 | }; 15 | 16 | int main() { 17 | std::cout << "fact<0>=" << fact<0>::value << std::endl; //output: fact<0>=1 18 | std::cout << "fact<10>=" << fact<10>::value << std::endl; //output: fact<10>=3628800 19 | 20 | //Lab: uncomments the following two lines, build and run this program, what are you expecting? 21 | //uint32_t m=5; 22 | //std::cout << fact::value << std::endl; 23 | } -------------------------------------------------------------------------------- /Chapter13/ch13_tdd_v1.cpp: -------------------------------------------------------------------------------- 1 | #include "ch13_tdd_v1.h" 2 | using namespace std; 3 | 4 | template< class T> 5 | Mat::Mat(const uint32_t m, const uint32_t n) 6 | : m_rows(m) 7 | , m_cols(n) 8 | , m_buf(NULL) 9 | { 10 | creatBuf(); 11 | } 12 | 13 | template< class T> 14 | Mat :: ~Mat() 15 | { 16 | deleteBuf(); 17 | } 18 | 19 | template< class T> 20 | void Mat::creatBuf() 21 | { 22 | uint32_t sz = m_rows * m_cols; 23 | if (sz > 0) { 24 | if (m_buf) { deleteBuf();} 25 | m_buf = new T[sz]; 26 | assert(m_buf); 27 | } 28 | else { 29 | m_buf = NULL; 30 | } 31 | } 32 | 33 | template< class T> 34 | void Mat::deleteBuf() 35 | { 36 | if (m_buf) { 37 | delete[] m_buf; 38 | m_buf = NULL; 39 | } 40 | } 41 | 42 | template< class T> 43 | void Mat ::print(const char* str) const 44 | { 45 | cout << str << endl; 46 | cout << m_rows << " x " << m_cols << "[" << endl; 47 | const T *p = m_buf; 48 | for (uint32_t i = 0; i 3 | template 4 | T app_max(T a, T b) { return (a>b ? a : b); } 5 | 6 | using namespace std; 7 | int main() { 8 | //implicit instantiation in an explicit way 9 | cout << app_max(5, 8) << endl; //instantiation as: int app_max(int,int) 10 | cout << app_max(5.0, 8.0) << endl; //instantiation as: float app_max(float, float> 11 | cout << app_max(5.0, 8) << endl; //instantiation as: int app_max(int,int) 12 | cout << app_max(5.0, 8) << endl; //instantiation as: double app_max(double, double) 13 | 14 | //implicit instantiation in an argument deduction way 15 | cout << app_max(5, 8) << endl; //deduced as int app_max(int,int) 16 | cout << app_max(5.0f, 8.0f) << endl; //deduced as int app_max(int,int) 17 | 18 | //implicit instantiation in a confuse way, depend on compiler, may have errors 19 | //cout << app_max(5, 8.0)<(double,double) or int app_max(int,int) ? return 0; 20 | } 21 | -------------------------------------------------------------------------------- /Chapter04/ch4_6_class_template_specialization.cpp: -------------------------------------------------------------------------------- 1 | //ex4_6_class_template_specialization.cpp 2 | #include 3 | 4 | //primary class template 5 | template 6 | struct X { 7 | X(T init) : m(init) {} 8 | T increase() { return ++m; } 9 | T m; 10 | }; 11 | 12 | //specialization for char, it's till a class template but with an additional member function toUpperCase() 13 | template <> //Note: no parameters inside <>, it tells compiler "hi i am a specialized template" 14 | struct X { //Note: argument char appears in <> after X, "Hi, this is specialized only for type char" 15 | X(char init) : m(init) {} 16 | char increase() { return (m<127) ? ++m : (m=-128); } 17 | char toUpperCase() { 18 | if ((m >= 'a') && (m <= 'z')) m += 'A' - 'a'; 19 | return m; 20 | } 21 | char m; 22 | }; 23 | 24 | int main() { 25 | X x1(5); //x1 is an object implicitly instantiated from primary class template X 26 | std::cout << x1.increase() << std::endl; 27 | X x2('b'); //x2 is an object instantiated from specialization template X 28 | std::cout << x2.toUpperCase() << std::endl; 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /Chapter12/2_networking.h: -------------------------------------------------------------------------------- 1 | class Networking 2 | { 3 | public: 4 | void start_server(); 5 | 6 | public: 7 | std::shared_ptr get_instance(); 8 | void remove_instance(); 9 | 10 | private: 11 | Networking(); 12 | ~Networking(); 13 | 14 | private: 15 | int socket_; 16 | sockaddr_in server_; 17 | std::vector clients_; 18 | 19 | private: 20 | static std::shared_ptr instance_ = nullptr; 21 | static int MAX_QUEUED_CONNECTIONS = 1; 22 | }; 23 | 24 | void Networking::start_server() 25 | { 26 | socket_ = socket(AF_INET, SOCK_STREAM, 0); 27 | // the following check is the only one in this code snippet 28 | // we skipped checking results of other functions for brevity, 29 | // you shouldn't omit them in your code 30 | if (socket_ < 0) { 31 | throw std::exception("Cannot create a socket"); 32 | } 33 | 34 | struct sockaddr_in server; 35 | server.sin_family = AF_INET; 36 | server.sin_port = htons(port); 37 | server.sin_addr.s_addr = INADDR_ANY; 38 | 39 | bind(s, (struct sockaddr*)&server, sizeof(server)); 40 | listen(s, MAX_QUEUED_CONNECTIONS); 41 | // the accept() should be here 42 | } -------------------------------------------------------------------------------- /Chapter13/ch13_rca_order_of_evaluation.cpp: -------------------------------------------------------------------------------- 1 | //ch13_rca_order_of_evaluation.cpp 2 | #include 3 | using namespace std; 4 | 5 | class A { 6 | public: 7 | A(int x) : v2(v1), v3(v2), v1(x) { 8 | }; 9 | void print() { 10 | cout << "v1=" << v1 << ", v2=" << v2 << ", v3=" << v3 << endl; 11 | }; 12 | protected: 13 | //bad: the order of the class member is confusing 14 | int v1, v2, v3; 15 | }; 16 | 17 | class B { 18 | public: 19 | //good: since the initialization order is: v1 -> v2, 20 | //after this we have: v1==x, v2==x. 21 | B(int x) : v1(x), v2(v1) {}; 22 | 23 | //wrong: since the initialization order is: v1 -> v2, 24 | //after this we have: v1==?, v2==x. 25 | B(float x) : v2(x), v1(v2) {}; 26 | void print() { 27 | cout << "v1=" << v1 << ", v2=" << v2 << endl; 28 | }; 29 | 30 | protected: 31 | int v1; //good, here the declaration order is clear 32 | int v2; 33 | }; 34 | 35 | int main() 36 | { 37 | A a(10); 38 | B b1(10), b2(3.0f); 39 | a.print(); //v1 = 10, v2 = 10, v3 = 10 for both debug and relase 40 | b1.print(); //v1 = 10, v2 = 10 for both debug and relase 41 | b2.print(); //v1 = -858993460, v2 = 3 for debug; v1=0,v2=3 for release. 42 | } 43 | 44 | 45 | -------------------------------------------------------------------------------- /Chapter04/ch4_12_template_type_argument.cpp: -------------------------------------------------------------------------------- 1 | //ch4_9_template_type_argument.cpp 2 | #include 3 | #include //for 'typeid' to work 4 | using namespace std; 5 | 6 | template class C {}; //class template with type template parameter 7 | template void f() { cout << "T" << endl; }; //function template with type template parameter 8 | template void f() { cout << "i=" << i << endl; }; //function template with non-type template parameter 9 | 10 | struct A; // incomplete type 11 | typedef struct {} B; // type alias to an unnamed type 12 | int main() { 13 | cout << typeid(A).name() << endl; 14 | cout << typeid(A*).name() << endl; 15 | cout << typeid(B).name() << endl; 16 | cout << typeid(int()).name() << endl; 17 | 18 | C x1; //ok: 'A' names a type 19 | C x2; //ok: 'A*' names a type 20 | C x3; //ok: 'B' names a type 21 | f(); //ok:, since int() is considered as a tpye, this calls f() with T as argument 22 | f<5>(); //ok:, since int() is considered as a tpye, this calls f() with T as argument 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /Chapter04/ch4_8_variadic_printf.cpp: -------------------------------------------------------------------------------- 1 | //ch4_8_variadic_printf.cpp 2 | //this program is tested on g++ (Ubuntu/Linaro 7.3.0-27ubuntu1~18.04) 7.3.0 3 | //it may have compile errors for other platforms 4 | #include 5 | 6 | //base function: recursive end 7 | void printf_vt(const char *s) 8 | { 9 | while (*s) { 10 | if (*s == '%' && *(++s) != '%') 11 | throw std::runtime_error("invalid format string: missing arguments"); 12 | std::cout << *s++; 13 | } 14 | } 15 | 16 | //recursive call 17 | template 18 | void printf_vt(const char *s, T value, Rest... rest) 19 | { 20 | while (*s) { 21 | if (*s == '%' && *(++s) != '%') { 22 | std::cout << value; 23 | printf_vt(s, rest...); // called even when *s is 0 but does nothing in that case 24 | return; 25 | } 26 | std::cout << *s++; 27 | } 28 | } 29 | 30 | int main() { 31 | int x = 10; 32 | float y = 3.6; 33 | std::string s = std::string("Variadic templates"); 34 | const char* msg = "%s can accept %i parameters (or %s), x=%d, y=%f\n"; 35 | printf(msg, s, 100, "more", x, y); //replace 's' by 's.c_str()' to prevent the output bug 36 | 37 | const char* msg2 = "% can accept % parameters (or %); x=%,y=%\n"; 38 | printf_vt(msg2, s, 100, "more", x, y); 39 | return 0; 40 | } -------------------------------------------------------------------------------- /Chapter16/query-parser.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Token 5 | { 6 | using Word = std::string; 7 | using Weight = int; 8 | Word value; 9 | std::unordered_map related; 10 | }; 11 | 12 | struct Query 13 | { 14 | std::string raw_query; 15 | std::string normalized_query; 16 | std::vector tokens; 17 | std::string dialog_id; // we will use this in Dialog Generator 18 | }; 19 | 20 | class QueryParser 21 | { 22 | public: 23 | static Query parse(const std::string& query_string, const std::string& dialog_id = "") 24 | { 25 | Query qr; 26 | qr.raw_query = query_string; qr.dialog_id = dialog_id; 27 | qr.tokens = QueryParser::tokenize(query_string); QueryParser::retrieve_word_relations(qr.tokens); return qr; 28 | } 29 | 30 | private: 31 | static std::vector tokenize(const std::string& raw_string) { 32 | // 1. split raw_string by space 33 | // 2. construct for each word a Token // 3. return the list of tokens 34 | } 35 | static void retrieve_word_relations(std::vector& tokens) { 36 | // for each token, request the Knowledge Base 37 | // to retrieve relations and update tokens list 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /Chapter03/12_using_class.cpp: -------------------------------------------------------------------------------- 1 | class Product { 2 | public: 3 | Product() = default; // default constructor 4 | Product(const Product&); // copy constructor 5 | Product(Product&&); // move constructor 6 | 7 | Product& operator=(const Product&) = default; 8 | Product& operator=(Product&&) = default; 9 | // destructor is not declared, should be generated by the compiler 10 | public: 11 | void set_name(const std::string&); 12 | std::string name() const; 13 | void set_availability(bool); 14 | bool available() const; 15 | // code omitted for brevity 16 | 17 | private: 18 | std::string name_; 19 | double price_; 20 | int rating_; 21 | bool available_; 22 | }; 23 | 24 | std::ostream& operator<<(std::ostream&, const Product&); 25 | std::istream& operator>>(std::istream&, Product&); 26 | 27 | Product create_apple() { 28 | Product apple; 29 | apple.set_name("Red apple"); 30 | apple.set_price("0.2"); 31 | apple.set_rating(5); 32 | apple.set_available(true); 33 | return apple; 34 | } 35 | 36 | int main() { 37 | Product red_apple = create_apple(); 38 | Product book; 39 | Product* ptr = &book; 40 | ptr->set_name("Alice in Wonderland"); 41 | ptr->set_price(6.80); 42 | std::cout << "I'm reading " << book.name() 43 | << " and I bought an apple for " << red_apple.price() 44 | << std::endl; 45 | } -------------------------------------------------------------------------------- /Chapter13/ch13_tdd_v2.cpp: -------------------------------------------------------------------------------- 1 | #include "ch13_tdd_v2.h" 2 | using namespace std; 3 | 4 | template< class T> 5 | Mat::Mat(const uint32_t m, const uint32_t n) 6 | : m_rows(m) 7 | , m_cols(n) 8 | , m_buf(NULL) 9 | { 10 | creatBuf(); 11 | } 12 | 13 | template< class T> 14 | Mat :: ~Mat() 15 | { 16 | deleteBuf(); 17 | } 18 | 19 | template< class T> 20 | Mat::Mat(const uint32_t m, const uint32_t n, const T initVal) 21 | : m_rows(m) 22 | , m_cols(n) 23 | , m_buf(NULL) 24 | { 25 | creatBuf(); 26 | for (int i = 0; i < m_rows*m_cols; ++i) { 27 | m_buf[i] = initVal; 28 | } 29 | } 30 | 31 | template< class T> 32 | void Mat::creatBuf() 33 | { 34 | uint32_t sz = m_rows * m_cols; 35 | if (sz > 0) { 36 | if (m_buf) { 37 | deleteBuf(); 38 | } 39 | 40 | m_buf = new T[sz]; 41 | assert(m_buf); 42 | } 43 | else { 44 | m_buf = NULL; 45 | } 46 | } 47 | 48 | template< class T> 49 | void Mat::deleteBuf() 50 | { 51 | if (m_buf) { 52 | delete[] m_buf; 53 | m_buf = NULL; 54 | } 55 | } 56 | 57 | template< class T> 58 | void Mat ::print(const char* str) const 59 | { 60 | cout << str << m_rows << "x" << m_cols << "[" << endl; 61 | const T *p = m_buf; 62 | for (uint32_t i = 0; i 5 | #include 6 | template< class T> 7 | class Mat { 8 | public: 9 | Mat(const uint32_t m=0, const uint32_t n=0); 10 | Mat(const uint32_t m, const uint32_t n, const T initVal); 11 | Mat(const Mat &rhs); 12 | ~Mat(); 13 | 14 | Mat& operator = (const Mat &rhs); 15 | 16 | //element-wise +,-,*,/ operators 17 | Mat operator + (const Mat &rhs); 18 | Mat operator - (const Mat &rhs); 19 | Mat operator * (const Mat &rhs); 20 | Mat operator / (const Mat &rhs); 21 | 22 | uint32_t rows() const { return m_rows; } 23 | uint32_t cols() const { return m_cols; } 24 | uint32_t numel() const { return m_rows * m_cols;} 25 | bool empty() { return 0==m_rows || 0==m_cols; } 26 | 27 | const T* data() const { 28 | return m_buf; 29 | } 30 | 31 | T* data2(){ 32 | return m_buf; 33 | } 34 | 35 | bool isSameSize(const Mat &x) const { 36 | return ( m_rows == x.rows() && m_cols == x.cols() ); 37 | } 38 | 39 | void print(const char* str) const; 40 | 41 | private: 42 | Mat elementWiseOp(const Mat &x, const Mat &y, const char flag); 43 | 44 | void creatBuf(); 45 | void deleteBuf(); 46 | uint32_t m_rows; //# of rows 47 | uint32_t m_cols; //# of cols 48 | T* m_buf; 49 | }; 50 | 51 | #include "ch13_tdd_v3.cpp" 52 | 53 | #endif 54 | 55 | -------------------------------------------------------------------------------- /Chapter13/ch13_tdd_Boost_UTF3.cpp: -------------------------------------------------------------------------------- 1 | // ch13_tdd_Boost_UTF3.cpp 2 | #define BOOST_TEST_MODULE tdd_test 3 | #include 4 | #include "ch13_tdd_v3.h" 5 | 6 | //declare we begin a test suite and name it "my_suite " 7 | BOOST_AUTO_TEST_SUITE(tdd_suite) 8 | 9 | //add the 1st test case 10 | BOOST_AUTO_TEST_CASE(test_case1) { 11 | Mat x(2, 3); 12 | x.print("int x="); 13 | BOOST_TEST(2 == x.rows()); 14 | BOOST_TEST(3 == x.cols()); 15 | 16 | Mat y; 17 | BOOST_TEST(0 == y.rows()); 18 | BOOST_TEST(0 == y.cols()); 19 | 20 | Mat z(1, 10); 21 | BOOST_TEST(1 == z.rows()); 22 | BOOST_TEST(10 == z.cols()); 23 | } 24 | 25 | //add the 2nd test case 26 | BOOST_AUTO_TEST_CASE(test_case2) 27 | { 28 | Mat x(2, 3, 10); 29 | x.print("int x="); 30 | BOOST_TEST( 6 == x.numel() ); 31 | BOOST_TEST( false == x.empty() ); 32 | 33 | Mat y; 34 | BOOST_TEST( 0 == y.numel() ); 35 | BOOST_TEST( y.empty() ); 36 | } 37 | 38 | //add the 3rd test case 39 | BOOST_AUTO_TEST_CASE(test_case3) 40 | { 41 | Mat x(2, 3, 10); 42 | x.print("float x="); 43 | Mat y(x); 44 | Mat z = x; 45 | y.print("float y="); 46 | z.print("float z="); 47 | 48 | Mat z1 = x + y; 49 | Mat z2 = x - y; 50 | Mat z3 = x * y; 51 | Mat z4 = x / y; 52 | 53 | z1.print("float z1="); 54 | z2.print("float z2="); 55 | z3.print("float z3="); 56 | z4.print("float z4="); 57 | } 58 | 59 | BOOST_AUTO_TEST_SUITE_END() //declare we end test suite 60 | 61 | -------------------------------------------------------------------------------- /Chapter03/13_using_class.cpp: -------------------------------------------------------------------------------- 1 | class Product { 2 | public: 3 | Product() = default; // default constructor 4 | Product(const Product&); // copy constructor 5 | Product(Product&&); // move constructor 6 | 7 | Product& operator=(const Product&) = default; 8 | Product& operator=(Product&&) = default; 9 | // destructor is not declared, should be generated by the compiler 10 | public: 11 | void set_name(const std::string&); 12 | std::string name() const; 13 | void set_availability(bool); 14 | bool available() const; 15 | // code omitted for brevity 16 | 17 | private: 18 | std::string name_; 19 | double price_; 20 | int rating_; 21 | bool available_; 22 | }; 23 | 24 | std::ostream& operator<<(std::ostream&, const Product&); 25 | std::istream& operator>>(std::istream&, Product&); 26 | 27 | void create_apple(Product& apple) { 28 | Product_set_name(apple, "Red apple"); 29 | Product_set_price(apple, 0.2); 30 | Product_set_rating(apple, 5); 31 | Product_set_available(apple, true); 32 | return; 33 | } 34 | 35 | int main() { 36 | Product red_apple; 37 | Product_constructor(red_apple); 38 | create_apple(red_apple); 39 | Product book; 40 | Product* ptr; 41 | Product_constructor(book); 42 | Product_set_name(*ptr, "Alice in Wonderland"); 43 | Product_set_price(*ptr, 6.80); 44 | std::ostream os = operator<<(std::cout, "I'm reading "); 45 | os = operator<<(os, Product_name(book)); 46 | os = operator<<(os, " and I bought an apple for "); 47 | os = operator<<(os, Product_price(red_apple)); 48 | operator<<(os, std::endl); 49 | // destructor calls are skipped because the compiler 50 | // will remove them as empty functions to optimize the code 51 | // Product_destructor(book); 52 | // Product_destructor(red_apple); 53 | } -------------------------------------------------------------------------------- /Chapter04/ch4_4_class_template_explicit_inst.cpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------ 2 | //ch4_4_class_template_explicit.cpp 3 | //Note: the original code and its explanations on page 133-134 is inaccuracy. 4 | // please use the comments in this file to understand the concept of 5 | // explicit instantiation definition 6 | // and 7 | // explicit instantiation declaration 8 | // 9 | // To build: 10 | // use: g++ -std=gnu++11 ch4_4_class_template_explicit_inst.cpp 11 | // 12 | // I applogy for the inaccuracy of the original presentation in the book. 13 | // 14 | // ---Shunguang wu, 07/02/2021 15 | //------------------------------------------------------------------------ 16 | #include 17 | 18 | //explicit instantiation declaration means we do not want to 19 | //instantiate such type in a template, you can set this flag 20 | //to 1 to save some compile time 21 | #define USE_EXPLICIT_INST_DECLARATION_4_INT 0 22 | 23 | using namespace std; 24 | template 25 | struct A { 26 | A(T init=0) : val(init) {} 27 | virtual T foo(); 28 | T val; 29 | }; 30 | 31 | template //T in this line is template parameter 32 | T A::foo() { //the 1st T refers to function return type, the T in <> specifies that this 33 | //function's template parameter is also the class template parameter 34 | return val; 35 | } 36 | 37 | //explicit instantiation definitation, it forces instantiation of struct A for type 38 | template struct A; 39 | 40 | #if USE_EXPLICIT_INST_DECLARATION_4_INT 41 | //explicit instantiation decalration of struct A for type 42 | //if we do not want to use A, the explicit instantiation decalration 43 | //could save some compile time for real world big projects 44 | extern template struct A; 45 | #else 46 | //explicit instantiation definitation for 47 | template struct A; 48 | #endif 49 | 50 | 51 | int main(void) { 52 | A x(5.1); 53 | 54 | #if !USE_EXPLICIT_INST_DECLARATION_4_INT 55 | A y(5); 56 | cout << "fD="< 5 | Mat::Mat(const uint32_t m, const uint32_t n) 6 | : m_rows(m) 7 | , m_cols(n) 8 | , m_buf(NULL) 9 | { 10 | creatBuf(); 11 | } 12 | 13 | template< class T> 14 | Mat :: ~Mat() 15 | { 16 | deleteBuf(); 17 | } 18 | 19 | template< class T> 20 | Mat::Mat(const uint32_t m, const uint32_t n, const T initVal) 21 | : m_rows(m) 22 | , m_cols(n) 23 | , m_buf(NULL) 24 | { 25 | creatBuf(); 26 | for (uint32_t i = 0; i < numel(); ++i) { 27 | m_buf[i] = initVal; 28 | } 29 | } 30 | 31 | template< class T> 32 | Mat::Mat(const Mat &rhs) 33 | : m_rows(rhs.rows()) 34 | , m_cols(rhs.cols()) 35 | , m_buf(NULL) 36 | { 37 | creatBuf(); 38 | if (m_buf) { 39 | memcpy(m_buf, rhs.data(), rhs.numel() * sizeof(T)); 40 | } 41 | } 42 | 43 | template< class T> 44 | Mat& Mat::operator=(const Mat &rhs) 45 | { 46 | if (this != &rhs) { 47 | m_rows = rhs.rows(); 48 | m_cols = rhs.cols(); 49 | if (numel() != rhs.numel()) { 50 | creatBuf(); 51 | } 52 | if (m_buf) { 53 | memcpy(m_buf, rhs.data(), rhs.numel() * sizeof(T)); 54 | } 55 | } 56 | return *this; 57 | } 58 | 59 | template< class T> 60 | Mat Mat::operator+(const Mat &rhs) 61 | { 62 | return elementWiseOp(*this, rhs, '+'); 63 | } 64 | 65 | template< class T> 66 | Mat Mat::operator-(const Mat &rhs) 67 | { 68 | return elementWiseOp(*this, rhs, '-'); 69 | } 70 | template< class T> 71 | Mat Mat::operator*(const Mat &rhs) 72 | { 73 | return elementWiseOp(*this, rhs, '*'); 74 | } 75 | 76 | template< class T> 77 | Mat Mat::operator/(const Mat &rhs) 78 | { 79 | return elementWiseOp(*this, rhs, '/'); 80 | } 81 | 82 | template< class T> 83 | Mat Mat::elementWiseOp(const Mat &x, const Mat &y, const char flag) 84 | { 85 | assert( x.numel() == y.numel() ); 86 | 87 | Mat z(x); 88 | const T* py = y.data(); 89 | T* pz = z.data2(); 90 | if (flag == '+') { 91 | for (uint32_t i = 0; i < x.numel(); ++i, ++py, ++pz) { 92 | *pz += *py; 93 | } 94 | } 95 | else if (flag == '-') { 96 | for (uint32_t i = 0; i < x.numel(); ++i, ++py, ++pz) { 97 | *pz -= *py; 98 | } 99 | } 100 | else if (flag == '*') { 101 | for (uint32_t i = 0; i < x.numel(); ++i, ++py, ++pz) { 102 | *pz *= *py; 103 | } 104 | } 105 | else if (flag == '/') { 106 | for (uint32_t i = 0; i < x.numel(); ++i, ++py, ++pz) { 107 | *pz /= *py; //todo:check *py is not zero 108 | } 109 | } 110 | return z; 111 | } 112 | 113 | template< class T> 114 | void Mat::creatBuf() 115 | { 116 | uint32_t sz = m_rows * m_cols; 117 | if (sz > 0) { 118 | if (m_buf) { 119 | deleteBuf(); 120 | } 121 | 122 | m_buf = new T[sz]; 123 | assert(m_buf); 124 | } 125 | else { 126 | m_buf = NULL; 127 | } 128 | } 129 | 130 | template< class T> 131 | void Mat::deleteBuf() 132 | { 133 | if (m_buf) { 134 | delete[] m_buf; 135 | m_buf = NULL; 136 | } 137 | } 138 | 139 | template< class T> 140 | void Mat ::print(const char* str) const 141 | { 142 | cout << str << m_rows << "x" << m_cols << "[" << endl; 143 | const T *p = m_buf; 144 | for (uint32_t i = 0; iAbout the Authors 7 | 8 | This is the code repository for [Expert C++](https://www.packtpub.com/product/expert-c/9781838552657?utm_source=github&utm_medium=repository&utm_campaign=9781838552657), published by Packt. 9 | 10 | **Become a proficient programmer by learning coding best practices with C++17 and C++20's latest features** 11 | 12 | ## What is this book about? 13 | C++ has evolved over the years and the latest release – C++20 – is now available. Since C++11, C++ has been constantly enhancing the language feature set. With the new version, you’ll explore an array of features such as concepts, modules, ranges, and coroutines. This book will be your guide to learning the intricacies of the language, techniques, C++ tools, and the new features introduced in C++20, while also helping you apply these when building modern and resilient software. 14 | 15 | This book covers the following exciting features: 16 | * Understand memory management and low-level programming in C++ to write secure and stable applications 17 | * Discover the latest C++20 features such as modules, concepts, ranges, and coroutines 18 | * Understand debugging and testing techniques and reduce issues in your programs 19 | * Design and implement GUI applications using Qt5 20 | * Use multithreading and concurrency to make your programs run faster 21 | * Develop high-end games by using the object-oriented capabilities of C++ 22 | * Explore AI and machine learning concepts with C++ 23 | 24 | If you feel this book is for you, get your [copy](https://www.amazon.com/dp/1838552650) today! 25 | 26 | https://www.packtpub.com/ 28 | 29 | ## Instructions and Navigations 30 | All of the code is organized into folders. For example, Chapter02. 31 | 32 | The code will look like the following: 33 | ``` 34 | #include 35 | #include 36 | ``` 37 | 38 | **Following is what you need for this book:** 39 | This C++ book is for experienced C++ developers who are looking to take their knowledge to the next level and perfect their skills in building professional-grade applications. 40 | 41 | 42 | We also provide a PDF file that has color images of the screenshots/diagrams used in this book. [Click here to download it](https://static.packt-cdn.com/downloads/9781838552657_ColorImages.pdf). 43 | 44 | ## Errata 45 | * Chapter 3, Page 93 In second figure the return type of operator overloaded + and - should be of type Money 46 | 47 | 48 | ## Get to Know the Author 49 | **Vardan Grigoryan** 50 | is a senior backend engineer and C++ developer with more than 9 years of experience. Vardan started his career as a C++ developer and then moved to the world of server-side backend development. While being involved in designing scalable backend architectures, he always tries to incorporate the use of C++ in critical sections that require the fastest execution time. Vardan loves tackling computer systems and program structures on a deeper level. He believes that true excellence in programming can be achieved by means of a detailed analysis of existing solutions and by designing complex systems. 51 | 52 | **Shunguang Wu** 53 | is a senior professional staff at Johns Hopkins University Applied Physics Laboratory, and received his PhDs in theoretical physics and electrical engineering from Northwestern University (China) and Wright State University (USA), respectively. He published about 50 reviewed journal papers in the area of nonlinear dynamics, statistical signal processing and computer vision in his early career. His professional C++ experience started with teaching undergraduate courses in the late 1990s. Since then he has been designing and developing lots of R&D and end-user application software using C++ in world-class academic and industrial laboratories. These projects span both the Windows and Linux platforms 54 | 55 | ### Download a free PDF 56 | 57 | If you have already purchased a print or Kindle version of this book, you can get a DRM-free PDF version at no cost.
Simply click on the link to claim your free PDF.
58 |

https://packt.link/free-ebook/9781838552657

--------------------------------------------------------------------------------