├── README.md └── source ├── MyInt.cpp ├── MyInt2.cpp ├── MyInt3.cpp ├── MyInt4.cpp ├── a.h ├── accountIsSmaller1.cpp ├── accountIsSmaller2.cpp ├── accountIsSmaller3.cpp ├── allExe.txt ├── argumentDependentLookup.cpp ├── argumentDependentLookupResolved.cpp ├── at.cpp ├── b.h ├── badCast.cpp ├── cStyle.c ├── classMemberInitializerWidget.cpp ├── classWithUniquePtr.cpp ├── cloneFunction.cpp ├── compare.cpp ├── conditionVariable.cpp ├── conditionVariablePingPong.cpp ├── conditionVariableWithoutPredicate.cpp ├── constexpr.cpp ├── convertingConstructor.cpp ├── createT1.cpp ├── createT2.cpp ├── cycle.cpp ├── dataRace.cpp ├── dataRaceOnX.cpp ├── dataRaceOnXCppMem.txt ├── dependendyInjection.cpp ├── differentReturnTypes.cpp ├── dimovAbrahams.cpp ├── doubleFree.cpp ├── enable_if.cpp ├── enumChecksRange.cpp ├── equalityOperator.cpp ├── equalityOperatorHierarchy.cpp ├── factorial.cpp ├── foldExpressions.cpp ├── forwarding.cpp ├── functionObjects.cpp ├── functionOverloading.cpp ├── functionTemplateSpecialization.cpp ├── gcd.cpp ├── gcd2.cpp ├── genericArray.cpp ├── genericArrayInheritance.cpp ├── gslCheck.cpp ├── gslCheckSuppress.cpp ├── immortal.cpp ├── implicitConversion.cpp ├── initialisationAssignment.cpp ├── isSmaller.cpp ├── lambdaFunctionCapture.cpp ├── lifecycle.c ├── lifecycle.cpp ├── lifetimeSemantic.cpp ├── lockGuardDeadlock.cpp ├── macro.cpp ├── main.cpp ├── makeUnique.cpp ├── mallocVersusNew.cpp ├── memberDeclarationOrder.cpp ├── memoryAccess.cpp ├── mixSignedUnsigend.cpp ├── modulo.cpp ├── mostVexingParse.cpp ├── mostVexingParseSolved.cpp ├── moveUniquePtr.cpp ├── mutable.cpp ├── myGuard.cpp ├── nakedUnion.cpp ├── namespaceDirective.cpp ├── namespaceDirectiveRemoved.cpp ├── narrowingConversion.cpp ├── narrowingConversionSolved.cpp ├── notGeneric.cpp ├── nullPointer.cpp ├── overUnderflow.cpp ├── overflow.cpp ├── overloadSet.cpp ├── overrider.cpp ├── ownershipSemantic.cpp ├── power.cpp ├── powerHybrid.cpp ├── primaryTypeCategories.cpp ├── printfIostreamsUndefinedBehavior.cpp ├── promiseFutureException.cpp ├── promiseFutureSynchronize.cpp ├── raii.cpp ├── records.cpp ├── relaxedSemantic.cpp ├── removeConst.cpp ├── returnPair.cpp ├── returnRvalueReference.cpp ├── sclice.cpp ├── scopedEnum.cpp ├── semiRegular.cpp ├── sequentialConsistency.cpp ├── shadow.cpp ├── shadowClass.cpp ├── signedTypes.cpp ├── singleton.cpp ├── singletonMeyers.cpp ├── sizeof.cpp ├── slice.cpp ├── sliceVirtuality.cpp ├── standaloneAllocation.cpp ├── strange.cpp ├── streamState.cpp ├── stringBoundsCheck.cpp ├── stringC.c ├── stringCpp.cpp ├── stringLiteral.cpp ├── stringView.cpp ├── structuredBinding.cpp ├── sumUp.cpp ├── sumUpFunctionObject.cpp ├── sumUpLambda.cpp ├── swap.cpp ├── switch.cpp ├── syncWithStdioPerformanceEndl.cpp ├── templateArgumentDeduction.cpp ├── threadCreationPerformance.cpp ├── threadDetach.cpp ├── threadSharesOwnership.cpp ├── threadSharesOwnershipSharedPtr.cpp ├── threadWithJoin.cpp ├── threadWithoutJoin.cpp ├── transformExclusiveScan.cpp ├── typeEnum.cpp ├── uniformInitialization.cpp ├── uniqPtrMove.cpp ├── uniqPtrReference.cpp ├── unspecified.cpp ├── vararg.cpp ├── variant.cpp ├── vectorMemory.cpp ├── virtualCall.cpp └── virtualMemberFunctions.cpp /README.md: -------------------------------------------------------------------------------- 1 | # C++ Core Guidelines: Best Practices for Modern C++ 2 | 3 | This is the code repository for my book [C++ Core Guidelines: Best Practices for Modern C++](https://www.pearson.com/us/higher-education/program/Grimm-C-Core-Guidelines-Explained-Best-Practices-for-Modern-C/PGM2928303.html) 4 | 5 | I put the name of the source file in the title of each source code example in the book. 6 | 7 | 8 | ## Description 9 | 10 | C++ expert instructor Rainer Grimm offers accessible, practical coverage of the Core Guidelines that offer the most value to students learning the C++ programming language. Offering new insights, indispensable context, and proven C++17 examples drawn from his courses and seminars, Grimm helps students get more value from the guidelines. 11 | 12 | Grimm’s wide-ranging coverage addresses C++ programming philosophy, interfaces, functions, classes, class hierarchies, enumerations, resource management, expressions, statements, performance, concurrency, error handling, constants, immutability, templates, generic programming, C-style programming, source files, the Standard Library, and more. Each section links to the original standard online, and wherever appropriate, Grimm previews advances from C++20 and C++23. With Grimm's Help, students can use the C++ Core Guidelines to write C++ code that's more consistent, robust, and well-performing. 13 | 14 | -------------------------------------------------------------------------------- /source/MyInt.cpp: -------------------------------------------------------------------------------- 1 | struct MyInt { 2 | MyInt(int v):val(v) {}; 3 | MyInt operator + (const MyInt& oth) const { 4 | return MyInt(val + oth.val); 5 | } 6 | int val; 7 | }; 8 | 9 | int main() { 10 | 11 | MyInt myFive = MyInt(2) + MyInt(3); 12 | MyInt myFive2 = MyInt(3) + MyInt(2); 13 | 14 | MyInt myTen = myFive + 5; 15 | MyInt myTen2 = 5 + myFive; 16 | 17 | } 18 | 19 | -------------------------------------------------------------------------------- /source/MyInt2.cpp: -------------------------------------------------------------------------------- 1 | class MyInt2 { 2 | public: 3 | MyInt2(int v):val(v) {}; 4 | friend MyInt2 operator + (const MyInt2& fir, const MyInt2& sec) { 5 | return MyInt2(fir.val + sec.val); 6 | } 7 | private: 8 | int val; 9 | }; 10 | 11 | int main() { 12 | 13 | MyInt2 myFive = MyInt2(2) + MyInt2(3); 14 | MyInt2 myFive2 = MyInt2(3) + MyInt2(2); 15 | 16 | MyInt2 myTen = myFive + 5; 17 | MyInt2 myTen2 = 5 + myFive; 18 | 19 | } 20 | 21 | -------------------------------------------------------------------------------- /source/MyInt3.cpp: -------------------------------------------------------------------------------- 1 | class MyInt3 { 2 | public: 3 | explicit MyInt3(int v):val(v) {}; 4 | friend MyInt3 operator + (const MyInt3& fir, const MyInt3& sec) { 5 | return MyInt3(fir.val + sec.val); 6 | } 7 | private: 8 | int val; 9 | }; 10 | 11 | int main() { 12 | 13 | MyInt3 myFive = MyInt3(2) + MyInt3(3); 14 | MyInt3 myFive2 = MyInt3(3) + MyInt3(2); 15 | 16 | MyInt3 myTen = myFive + 5; 17 | MyInt3 myTen2 = 5 + myFive; 18 | 19 | } 20 | 21 | -------------------------------------------------------------------------------- /source/MyInt4.cpp: -------------------------------------------------------------------------------- 1 | class MyInt4 { 2 | public: 3 | explicit MyInt4(int v):val(v) {}; 4 | friend MyInt4 operator + (const MyInt4& fir, const MyInt4& sec) { 5 | return MyInt4(fir.val + sec.val); 6 | } 7 | friend MyInt4 operator + (const MyInt4& fir, int sec) { 8 | return MyInt4(fir.val + sec); 9 | } 10 | friend MyInt4 operator + (int fir, const MyInt4& sec) { 11 | return MyInt4(fir + sec.val); 12 | } 13 | private: 14 | int val; 15 | }; 16 | 17 | int main() { 18 | 19 | MyInt4 myFive = MyInt4(2) + MyInt4(3); 20 | MyInt4 myFive2 = MyInt4(3) + MyInt4(2); 21 | 22 | MyInt4 myTen = myFive + 5; 23 | MyInt4 myTen2 = 5 + myFive; 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /source/a.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRARY_A_H 2 | #define LIBRARY_A_H 3 | #include "b.h" 4 | 5 | class A { 6 | B b; 7 | }; 8 | 9 | #endif // LIBRARY_A_H -------------------------------------------------------------------------------- /source/accountIsSmaller1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class Account { 4 | public: 5 | Account() = default; 6 | Account(double b): balance(b) {} 7 | friend bool operator < (Account const& fir, Account const& sec) { 8 | return fir.getBalance() < sec.getBalance(); 9 | } 10 | double getBalance() const { 11 | return balance; 12 | } 13 | private: 14 | double balance{0.0}; 15 | }; 16 | 17 | template 18 | bool isSmaller(T fir, T sec) { 19 | return fir < sec; 20 | } 21 | 22 | int main() { 23 | 24 | std::cout << std::boolalpha << '\n'; 25 | 26 | double firDou{}; 27 | double secDou{2014.0}; 28 | 29 | std::cout << "isSmaller(firDou, secDou): " 30 | << isSmaller(firDou, secDou) << '\n'; 31 | 32 | Account firAcc{}; 33 | Account secAcc{2014.0}; 34 | 35 | std::cout << "isSmaller(firAcc, secAcc): " 36 | << isSmaller(firAcc, secAcc) << '\n'; 37 | 38 | std::cout << '\n'; 39 | 40 | } 41 | -------------------------------------------------------------------------------- /source/accountIsSmaller2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class Account{ 4 | public: 5 | Account() = default; 6 | Account(double b): balance(b) {} 7 | double getBalance() const { 8 | return balance; 9 | } 10 | private: 11 | double balance{0.0}; 12 | }; 13 | 14 | template 15 | bool isSmaller(T fir, T sec){ 16 | return fir < sec; 17 | } 18 | 19 | template<> 20 | bool isSmaller(Account fir, Account sec){ 21 | return fir.getBalance() < sec.getBalance(); 22 | } 23 | 24 | int main() { 25 | 26 | std::cout << std::boolalpha << '\n'; 27 | 28 | double firDou{}; 29 | double secDou{2014.0}; 30 | 31 | std::cout << "isSmaller(firDou, secDou): " 32 | << isSmaller(firDou, secDou) << '\n'; 33 | 34 | Account firAcc{}; 35 | Account secAcc{2014.0}; 36 | 37 | std::cout << "isSmaller(firAcc, secAcc): " 38 | << isSmaller(firAcc, secAcc) << '\n'; 39 | 40 | std::cout << '\n'; 41 | 42 | } 43 | -------------------------------------------------------------------------------- /source/accountIsSmaller3.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | class Account { 6 | public: 7 | Account() = default; 8 | Account(double b): balance(b){} 9 | double getBalance() const { 10 | return balance; 11 | } 12 | private: 13 | double balance{0.0}; 14 | }; 15 | 16 | template > 17 | bool isSmaller(T fir, T sec, Pred pred = Pred() ) { 18 | return pred(fir, sec); 19 | } 20 | 21 | int main() { 22 | 23 | std::cout << std::boolalpha << '\n'; 24 | 25 | double firDou{}; 26 | double secDou{2014.0}; 27 | 28 | std::cout << "isSmaller(firDou, secDou): " 29 | << isSmaller(firDou, secDou) << '\n'; 30 | 31 | Account firAcc{}; 32 | Account secAcc{2014.0}; 33 | 34 | auto res = isSmaller(firAcc, secAcc, 35 | [](const Account& fir, const Account& sec){ 36 | return fir.getBalance() < sec.getBalance(); 37 | } 38 | ); 39 | 40 | std::cout << "isSmaller(firAcc, secAcc): " << res << '\n'; 41 | 42 | std::cout << '\n'; 43 | 44 | std::string firStr = "AAA"; 45 | std::string secStr = "BB"; 46 | 47 | std::cout << "isSmaller(firStr, secStr): " 48 | << isSmaller(firStr, secStr) << '\n'; 49 | 50 | auto res2 = isSmaller(firStr, secStr, 51 | [](const std::string& fir, const std::string& sec){ 52 | return fir.length() < sec.length(); 53 | } 54 | ); 55 | 56 | std::cout << "isSmaller(firStr, secStr): " << res2 << '\n'; 57 | 58 | std::cout << '\n'; 59 | 60 | } 61 | -------------------------------------------------------------------------------- /source/allExe.txt: -------------------------------------------------------------------------------- 1 | accountIsSmaller1.cpp 2 | accountIsSmaller2.cpp 3 | accountIsSmaller3.cpp 4 | allExe.txt 5 | argumentDependentLookup.cpp 6 | argumentDependentLookupResolved.cpp 7 | at.cpp 8 | badCast.cpp 9 | classMemberInitializerWidget.cpp 10 | classWithUniquePtr.cpp 11 | cloneFunction.cpp 12 | compare.cpp 13 | compare.Traits 14 | conditionVariable.cpp 15 | conditionVariablePingPong.cpp 16 | conditionVariableWithoutPredicate.cpp 17 | constexpr.cpp 18 | convertingConstructor.cpp 19 | createT1.cpp 20 | createT2.cpp 21 | cStyle.c 22 | cycle.cpp 23 | dataRace.cpp 24 | dataRaceOnX.cpp 25 | dataRaceOnXCppMem.txt 26 | differentReturnTypes.cpp 27 | dimovAbrahams.cpp 28 | doubleFree.cpp 29 | enable_if.cpp 30 | equalityOperator.cpp 31 | factorial.cpp 32 | foldExpressions.cpp 33 | forwarding.cpp 34 | functionObjects.cpp 35 | functionOverloading.cpp 36 | functionTemplateSpecialization.cpp 37 | gcd2.cpp 38 | gcd.cpp 39 | genericArray.cpp 40 | genericArrayInheritance.cpp 41 | gslCheck.cpp 42 | gslCheckSuppress.cpp 43 | immortal.cpp 44 | implicitConversion.cpp 45 | initialisationAssignment.cpp 46 | isSmaller.cpp 47 | lambdaFunctionCapture.cpp 48 | lifecycle.c 49 | lifecycle.cpp 50 | lifetimeSemantic.cpp 51 | lockGuardDeadlock.cpp 52 | macro.c 53 | makeUnique.cpp 54 | mallocVersusNew.cpp 55 | memberDeclarationOrder.cpp 56 | memoryAccess.cpp 57 | mixSignedUnsigend.cpp 58 | modulo.cpp 59 | mostVexingParse.cpp 60 | mostVexingParseSolved.cpp 61 | moveUniquePtr.cpp 62 | mutable.cpp 63 | myGuard.cpp 64 | MyInt2.cpp 65 | MyInt3.cpp 66 | MyInt4.cpp 67 | MyInt.cpp 68 | nakedUnion.cpp 69 | namespaceDirective.cpp 70 | narrowingConversion.cpp 71 | narrowingConversionSolved.cpp 72 | newAlgorithms.cpp 73 | notGeneric.cpp 74 | nullPointer.cpp 75 | overflow.cpp 76 | overloadSet.cpp 77 | overrider.cpp 78 | overUnderflow.cpp 79 | ownershipSemantic.cpp 80 | power.cpp 81 | powerHybrid.cpp 82 | primaryTypeCategories.cpp 83 | printfIostreamsUndefinedBehavior.cpp 84 | promiseFutureException.cpp 85 | promiseFutureSynchronize.cpp 86 | raii.cpp 87 | records.cpp 88 | relaxedSemantic.cpp 89 | returnPair.cpp 90 | returnRvalueReference.cpp 91 | sclice.cpp 92 | scopedEnum.cpp 93 | semiRegular.cpp 94 | sequentialConsistency.cpp 95 | shadowClass.cpp 96 | shadow.cpp 97 | signedTypes.cpp 98 | singleton.cpp 99 | singletonMeyers.cpp 100 | sizeof.cpp 101 | slice.cpp 102 | sliceVirtuality.cpp 103 | standaloneAllocation.cpp 104 | strange.cpp 105 | streamState.cpp 106 | stringBoundsCheck.cpp 107 | stringC.c 108 | stringCpp.cpp 109 | stringLiteral.cpp 110 | stringView.cpp 111 | stronglyTypedEnum.cpp 112 | structuredBinding.cpp 113 | sumUp.cpp 114 | sumUpFunctionObject.cpp 115 | sumUpLambda.cpp 116 | swap.cpp 117 | switch.cpp 118 | syncWithStdioPerformanceEndl.cpp 119 | templateArgumentDeduction.cpp 120 | threadCreationPerformance.cpp 121 | threadDetach.cpp 122 | threadSharesOwnership.cpp 123 | threadSharesOwnershipSmartPtr.cpp 124 | threadWithJoin.cpp 125 | threadWithoutJoin.cpp 126 | transformExclusiveScan.cpp 127 | typeEnum.cpp 128 | uniformInitialization.cpp 129 | uniqPtrMove.cpp 130 | uniqPtrReference.cpp 131 | unspecified.cpp 132 | vararg.cpp 133 | variant.cpp 134 | vectorMemory.cpp 135 | virtualCall.cpp 136 | virtualMemberFunctions.cpp 137 | -------------------------------------------------------------------------------- /source/argumentDependentLookup.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | namespace Bad { 5 | 6 | struct Number { 7 | int m; 8 | }; 9 | 10 | template 11 | bool operator == (T1, T2) { 12 | return false; 13 | } 14 | 15 | } 16 | 17 | namespace Util { 18 | 19 | bool operator == (int, Bad::Number) { 20 | return true; 21 | } 22 | 23 | void compareSize() { 24 | Bad::Number badNumber{5}; 25 | std::vector vec{1, 2, 3, 4, 5}; 26 | 27 | std::cout << std::boolalpha << '\n'; 28 | 29 | std::cout << "5 == badNumber: " << 30 | (5 == badNumber) << '\n'; 31 | std::cout << "vec.size() == badNumber: " << 32 | (vec.size() == badNumber) << '\n'; 33 | 34 | std::cout << '\n'; 35 | } 36 | } 37 | 38 | int main() { 39 | 40 | Util::compareSize(); 41 | 42 | } 43 | -------------------------------------------------------------------------------- /source/argumentDependentLookupResolved.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | namespace Bad { 5 | 6 | struct Number { 7 | int m; 8 | }; 9 | 10 | } 11 | 12 | namespace Util { 13 | 14 | bool operator == (int, Bad::Number) { // compare to int 15 | return true; 16 | } 17 | 18 | void compareSize() { 19 | Bad::Number badNumber{5}; 20 | std::vector vec{1, 2, 3, 4, 5}; 21 | 22 | std::cout << std::boolalpha << '\n'; 23 | 24 | std::cout << "5 == badNumber: " << 25 | (5 == badNumber) << '\n'; 26 | std::cout << "vec.size() == badNumber: " << 27 | (vec.size() == badNumber) << '\n'; 28 | 29 | std::cout << '\n'; 30 | } 31 | } 32 | 33 | int main() { 34 | 35 | Util::compareSize(); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /source/at.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | template 8 | void use(T*, int) {} 9 | 10 | template 11 | void f(T& a) { 12 | 13 | if (a.size() < 2) return; 14 | 15 | int n = a.at(0); 16 | 17 | std::array q; 18 | std::copy(a.begin() + 1, a.end(), q.begin()); 19 | 20 | if (a.size() < 6) return; 21 | 22 | a.at(4) = 1; 23 | 24 | a.at(a.size() - 1) = 2; 25 | 26 | use(a.data(), a.size()); 27 | } 28 | 29 | int main() { 30 | 31 | std::array arr{}; 32 | f(arr); 33 | 34 | std::array arr2{}; 35 | f(arr2); 36 | 37 | std::vector vec{1, 2, 3, 4, 5, 6, 7, 8, 9}; 38 | f(vec); 39 | 40 | std::string myString= "123456789"; 41 | f(myString); 42 | 43 | // std::deque deq{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 44 | // f(deq); 45 | 46 | } 47 | -------------------------------------------------------------------------------- /source/b.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRARY_B_H 2 | #define LIBRARY_B_H 3 | #include "a.h" 4 | 5 | class B { 6 | A a; 7 | }; 8 | 9 | #endif // LIBRARY_B_H -------------------------------------------------------------------------------- /source/badCast.cpp: -------------------------------------------------------------------------------- 1 | // badCast.cpp 2 | 3 | struct Base { 4 | virtual void f() {} 5 | }; 6 | struct Derived : Base {}; 7 | 8 | int main() { 9 | 10 | Base a; 11 | 12 | Derived* b1 = dynamic_cast(&a); // nullptr 13 | Derived& b2 = dynamic_cast(a); // std::bad_cast 14 | 15 | } 16 | -------------------------------------------------------------------------------- /source/cStyle.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | 5 | double sq2 = sqrt(2); 6 | 7 | printf("\nsizeof(\'a\'): %d\n\n", sizeof('a')); 8 | 9 | char c; 10 | void* pv = &c; 11 | int* pi = pv; 12 | 13 | int class = 5; 14 | 15 | } 16 | -------------------------------------------------------------------------------- /source/classMemberInitializerWidget.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class Widget { 4 | public: 5 | Widget(): width(640), height(480), frame(false), visible(true) {} 6 | explicit Widget(int w): width(w), height(getHeight(w)), frame(false), visible(true) {} 7 | Widget(int w, int h): width(w), height(h), frame(false), visible(true) {} 8 | 9 | void show() const { std::cout << std::boolalpha << width << "x" << height 10 | << ", frame: " << frame << ", visible: " << visible 11 | << '\n'; 12 | } 13 | private: 14 | int getHeight(int w) { return w*3/4; } 15 | int width; 16 | int height; 17 | bool frame; 18 | bool visible; 19 | }; 20 | 21 | class WidgetImpro { 22 | public: 23 | WidgetImpro() = default; 24 | explicit WidgetImpro(int w): width(w), height(getHeight(w)) {} 25 | WidgetImpro(int w, int h): width(w), height(h) {} 26 | 27 | void show() const { std::cout << std::boolalpha << width << "x" << height 28 | << ", frame: " << frame << ", visible: " << visible 29 | << '\n'; 30 | } 31 | 32 | private: 33 | int getHeight(int w) { return w * 3 / 4; } 34 | int width{640}; 35 | int height{480}; 36 | bool frame{false}; 37 | bool visible{true}; 38 | }; 39 | 40 | 41 | int main() { 42 | 43 | std::cout << '\n'; 44 | 45 | Widget wVGA; 46 | Widget wSVGA(800); 47 | Widget wHD(1280, 720); 48 | 49 | wVGA.show(); 50 | wSVGA.show(); 51 | wHD.show(); 52 | 53 | std::cout << '\n'; 54 | 55 | WidgetImpro wImproVGA; 56 | WidgetImpro wImproSVGA(800); 57 | WidgetImpro wImproHD(1280, 720); 58 | 59 | wImproVGA.show(); 60 | wImproSVGA.show(); 61 | wImproHD.show(); 62 | 63 | std::cout << '\n'; 64 | 65 | } 66 | -------------------------------------------------------------------------------- /source/classWithUniquePtr.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct MyClass { 4 | std::unique_ptr uniPtr = std::make_unique(2011); 5 | }; 6 | 7 | int main() { 8 | 9 | MyClass myClass; 10 | MyClass myClass2(myClass); 11 | MyClass myClass3; 12 | myClass3 = myClass; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /source/cloneFunction.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct Base { // GOOD: base class suppresses copying 6 | Base() = default; 7 | virtual ~Base() = default; 8 | Base(const Base&) = delete; 9 | Base& operator = (const Base&) = delete; 10 | virtual std::unique_ptr clone() { return std::make_unique(); } 11 | virtual std::string getName() const { return "Base"; } 12 | }; 13 | 14 | struct Derived : public Base { 15 | Derived() = default; 16 | std::unique_ptr clone() override { return std::make_unique(); } 17 | std::string getName() const override { return "Derived"; } 18 | }; 19 | 20 | int main() { 21 | 22 | std::cout << '\n'; 23 | 24 | auto base1 = std::make_unique(); 25 | auto base2 = base1->clone(); 26 | std::cout << "base1->getName(): " << base1->getName() << '\n'; 27 | std::cout << "base2->getName(): " << base2->getName() << '\n'; 28 | 29 | auto derived1 = std::make_unique(); 30 | auto derived2 = derived1->clone(); 31 | std::cout << "derived1->getName(): " << derived1->getName() << '\n'; 32 | std::cout << "derived2->getName(): " << derived2->getName() << '\n'; 33 | 34 | std::cout << '\n'; 35 | 36 | } 37 | -------------------------------------------------------------------------------- /source/compare.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | class Base{}; 6 | class Derived: public Base{}; 7 | 8 | int main() { 9 | 10 | std::cout << std::boolalpha << '\n'; 11 | 12 | std::cout << "std::is_base_of::value: " 13 | << std::is_base_of::value << '\n'; 14 | std::cout << "std::is_base_of::value: " 15 | << std::is_base_of::value << '\n'; 16 | std::cout << "std::is_base_of::value: " 17 | << std::is_base_of::value << '\n'; 18 | 19 | std::cout << '\n'; 20 | 21 | std::cout << "std::is_convertible::value: " 22 | << std::is_convertible::value << '\n'; 23 | std::cout << "std::is_convertible::value: " 24 | << std::is_convertible::value << '\n'; 25 | std::cout << "std::is_convertible::value: " 26 | << std::is_convertible::value << '\n'; 27 | 28 | std::cout << '\n'; 29 | 30 | std::cout << "std::is_same::value: " 31 | << std::is_same::value << '\n'; 32 | std::cout << "std::is_same::value: " 33 | << std::is_same::value << '\n'; 34 | std::cout << "std::is_same::value: " 35 | << std::is_same::value << '\n'; 36 | 37 | std::cout << '\n'; 38 | 39 | } 40 | -------------------------------------------------------------------------------- /source/conditionVariable.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | std::mutex mut; 7 | std::condition_variable condVar; 8 | 9 | bool dataReady{false}; 10 | 11 | void waitingForWork() { 12 | std::cout << "Waiting " << '\n'; 13 | std::unique_lock lck(mut); 14 | condVar.wait(lck, []{ return dataReady; }); 15 | std::cout << "Running " << '\n'; 16 | } 17 | 18 | void setDataReady() { 19 | { 20 | std::lock_guard lck(mut); 21 | dataReady = true; 22 | } 23 | std::cout << "Data prepared" << '\n'; 24 | condVar.notify_one(); 25 | } 26 | 27 | int main() { 28 | 29 | std::cout << '\n'; 30 | 31 | std::thread t1(waitingForWork); 32 | std::thread t2(setDataReady); 33 | 34 | t1.join(); 35 | t2.join(); 36 | 37 | std::cout << '\n'; 38 | 39 | } 40 | -------------------------------------------------------------------------------- /source/conditionVariablePingPong.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | bool dataReady= false; 6 | 7 | std::mutex mut; 8 | std::condition_variable condVar1; 9 | std::condition_variable condVar2; 10 | 11 | int counter = 0; 12 | int COUNTLIMIT = 50; 13 | 14 | void setTrue() { 15 | 16 | while(counter <= COUNTLIMIT) { 17 | std::unique_lock lck(mut); 18 | condVar1.wait(lck, []{return dataReady == false;}); 19 | dataReady = true; 20 | ++counter; 21 | std::cout << dataReady << '\n'; 22 | condVar2.notify_one(); 23 | } 24 | } 25 | 26 | void setFalse() { 27 | 28 | while(counter < COUNTLIMIT) { 29 | std::unique_lock lck(mut); 30 | condVar2.wait(lck, []{return dataReady == true;}); 31 | dataReady = false; 32 | std::cout << dataReady << '\n'; 33 | condVar1.notify_one(); 34 | } 35 | } 36 | 37 | int main() { 38 | 39 | std::cout << std::boolalpha << '\n'; 40 | 41 | std::cout << "Begin: " << dataReady << '\n'; 42 | 43 | std::thread t1(setTrue); 44 | std::thread t2(setFalse); 45 | 46 | t1.join(); 47 | t2.join(); 48 | 49 | dataReady = false; 50 | std::cout << "End: " << dataReady << '\n'; 51 | 52 | std::cout << '\n'; 53 | 54 | } 55 | -------------------------------------------------------------------------------- /source/conditionVariableWithoutPredicate.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | std::mutex mut; 7 | std::condition_variable condVar; 8 | 9 | void waitingForWork() { 10 | std::cout << "Waiting " << '\n'; 11 | std::unique_lock lck(mut); 12 | condVar.wait(lck); 13 | std::cout << "Running " << '\n'; 14 | } 15 | 16 | void setDataReady() { 17 | std::cout << "Data prepared" << '\n'; 18 | condVar.notify_one(); 19 | } 20 | 21 | int main() { 22 | 23 | std::cout << '\n'; 24 | 25 | std::thread t1(waitingForWork); 26 | std::thread t2(setDataReady); 27 | 28 | t1.join(); 29 | t2.join(); 30 | 31 | std::cout << '\n'; 32 | 33 | } 34 | -------------------------------------------------------------------------------- /source/constexpr.cpp: -------------------------------------------------------------------------------- 1 | constexpr auto gcd(int a, int b) { 2 | while (b != 0){ 3 | auto t = b; 4 | b = a % b; 5 | a = t; 6 | } 7 | return a; 8 | } 9 | 10 | int main() { 11 | 12 | constexpr int i = gcd(11, 121); 13 | 14 | int a = 11; 15 | int b = 121; 16 | int j = gcd(a, b); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /source/convertingConstructor.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | namespace Distance { 6 | class MyDistance { 7 | public: 8 | MyDistance(double d):m(d) {} 9 | 10 | friend MyDistance operator + (const MyDistance& a, const MyDistance& b) { 11 | return MyDistance(a.m + b.m); 12 | } 13 | friend std::ostream& operator << (std::ostream &out, const MyDistance& myDist) { 14 | out << myDist.m << " m"; 15 | return out; 16 | } 17 | private: 18 | double m; 19 | 20 | }; 21 | 22 | namespace Unit{ 23 | MyDistance operator "" _km(long double d) { 24 | return MyDistance(1000*d); 25 | } 26 | MyDistance operator "" _m(long double m) { 27 | return MyDistance(m); 28 | } 29 | MyDistance operator "" _dm(long double d) { 30 | return MyDistance(d/10); 31 | } 32 | MyDistance operator "" _cm(long double c) { 33 | return MyDistance(c/100); 34 | } 35 | } 36 | } 37 | 38 | using namespace Distance::Unit; 39 | 40 | int main() { 41 | 42 | std:: cout << std::setprecision(7) << "\n"; 43 | 44 | std::cout << "1.0_km + 2.0_dm + 3.0_cm: " << 1.0_km + 2.0_dm + 3.0_cm << "\n"; 45 | std::cout << "4.2_km + 5.5_dm + 10.0_m + 0.3_cm: " << 4.2_km + 5.5 + 10.0_m + 0.3_cm << "\n"; 46 | 47 | std::cout << "\n"; 48 | 49 | } 50 | -------------------------------------------------------------------------------- /source/createT1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct MyType { 4 | MyType(int, double, bool) {}; 5 | }; 6 | 7 | template 8 | T createT(Arg&& arg) { 9 | return T(std::forward(arg)); 10 | } 11 | 12 | int main() { 13 | 14 | int lvalue{2020}; 15 | 16 | //std::unique_ptr uniqZero = std::make_unique(); 17 | auto uniqEleven = createT(2011); 18 | auto uniqTwenty = createT(lvalue); 19 | //auto uniqType = std::make_unique(lvalue, 3.14, true); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /source/createT2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct MyType { 4 | MyType(int, double, bool) {}; 5 | }; 6 | 7 | template 8 | T createT(Args&& ... args) { 9 | return T(std::forward(args) ... ); 10 | } 11 | 12 | int main() { 13 | 14 | int lvalue{2020}; 15 | 16 | int uniqZero = createT(); 17 | auto uniqEleven = createT(2011); 18 | auto uniqTwenty = createT(lvalue); 19 | auto uniqType = createT(lvalue, 3.14, true); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /source/cycle.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Son; 5 | struct Daughter; 6 | 7 | struct Mother { 8 | ~Mother() { 9 | std::cout << "Mother gone" << '\n'; 10 | } 11 | void setSon(const std::shared_ptr s) { 12 | mySon = s; 13 | } 14 | void setDaughter(const std::shared_ptr d) { 15 | myDaughter = d; 16 | } 17 | std::shared_ptr mySon; 18 | std::weak_ptr myDaughter; 19 | }; 20 | 21 | struct Son { 22 | explicit Son(std::shared_ptr m): myMother(m) {} 23 | ~Son() { 24 | std::cout << "Son gone" << '\n'; 25 | } 26 | std::shared_ptr myMother; 27 | }; 28 | 29 | struct Daughter { 30 | explicit Daughter(std::shared_ptr m): myMother(m) {} 31 | ~Daughter() { 32 | std::cout << "Daughter gone" << '\n'; 33 | } 34 | std::shared_ptr myMother; 35 | }; 36 | 37 | int main() { 38 | 39 | std::shared_ptr m = std::make_shared(); 40 | std::shared_ptr s = std::make_shared(m); 41 | std::shared_ptr d = std::make_shared(m); 42 | m->setSon(s); 43 | m->setDaughter(d); 44 | 45 | } 46 | -------------------------------------------------------------------------------- /source/dataRace.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int getUniqueId() { 4 | static int id = 1; 5 | return id++; 6 | } 7 | 8 | int main() { 9 | 10 | auto fut1 = std::async([]{ return getUniqueId(); }); 11 | auto fut2 = std::async([]{ return getUniqueId(); }); 12 | 13 | auto id = fut1.get(); 14 | auto id2= fut2.get(); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /source/dataRaceOnX.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int x = 0; 6 | std::atomic y{0}; 7 | 8 | void writing() { 9 | x = 2000; 10 | y.store(11); 11 | } 12 | 13 | void reading(){ 14 | std::cout << y.load() << " "; 15 | std::cout << x << '\n'; 16 | } 17 | 18 | int main() { 19 | 20 | std::thread thread1(writing); 21 | std::thread thread2(reading); 22 | 23 | thread1.join(); 24 | thread2.join(); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /source/dataRaceOnXCppMem.txt: -------------------------------------------------------------------------------- 1 | int main(){ 2 | int x = 0; 3 | atomic_int y = 0; 4 | 5 | {{{ 6 | { 7 | x = 2000; 8 | y.store(11); 9 | } 10 | ||| 11 | { 12 | y.load(); 13 | x; 14 | } 15 | }}} 16 | } 17 | -------------------------------------------------------------------------------- /source/dependendyInjection.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | class Logger { 6 | public: 7 | virtual void write(const std::string&) = 0; 8 | virtual ~Logger() = default; 9 | }; 10 | 11 | class SimpleLogger: public Logger { 12 | void write(const std::string& mess) override { 13 | std::cout << mess << std::endl; 14 | } 15 | }; 16 | 17 | class TimeLogger: public Logger { 18 | using MySecondTick = std::chrono::duration; 19 | long double timeSinceEpoch() { 20 | auto timeNow = std::chrono::system_clock::now(); 21 | auto duration = timeNow.time_since_epoch(); 22 | MySecondTick sec(duration); 23 | return sec.count(); 24 | } 25 | void write(const std::string& mess) override { 26 | std::cout << std::fixed; 27 | std::cout << "Time since epoch: " << timeSinceEpoch() << ": " << mess << std::endl; 28 | } 29 | 30 | }; 31 | 32 | class Client { 33 | public: 34 | Client(std::shared_ptr log): logger(log) {} 35 | void doSomething() { 36 | logger->write("Message"); 37 | } 38 | void setLogger(std::shared_ptr log) { 39 | logger = log; 40 | } 41 | private: 42 | std::shared_ptr logger; 43 | }; 44 | 45 | 46 | int main() { 47 | 48 | std::cout << std::endl; 49 | 50 | Client cl(std::make_shared()); 51 | cl.doSomething(); 52 | cl.setLogger(std::make_shared()); 53 | cl.doSomething(); 54 | cl.doSomething(); 55 | 56 | std::cout << std::endl; 57 | 58 | } 59 | -------------------------------------------------------------------------------- /source/differentReturnTypes.cpp: -------------------------------------------------------------------------------- 1 | template 2 | auto getValue(T x) { 3 | if (x < 0) // int 4 | return -1; 5 | else if (x > 0) 6 | return 1.0; // double 7 | else return 0.0f; // float 8 | } 9 | 10 | int main(){ 11 | getValue(5.5); 12 | } 13 | -------------------------------------------------------------------------------- /source/dimovAbrahams.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // getTypeName 5 | 6 | template // primary template 7 | std::string getTypeName(T) { 8 | return "unknown"; 9 | } 10 | 11 | template // primary template that overloads (1) 12 | std::string getTypeName(T*) { 13 | return "pointer"; 14 | } 15 | 16 | template<> // explicit specialization of (2) 17 | std::string getTypeName(int*) { 18 | return "int pointer"; 19 | } 20 | 21 | // getTypeName2 22 | 23 | template // primary template 24 | std::string getTypeName2(T) { 25 | return "unknown"; 26 | } 27 | 28 | template<> // explicit specialization of (4) 29 | std::string getTypeName2(int*) { 30 | return "int pointer"; 31 | } 32 | 33 | template // primary template that overloads (4) 34 | std::string getTypeName2(T*) { 35 | return "pointer"; 36 | } 37 | 38 | int main() { 39 | 40 | std::cout << '\n'; 41 | 42 | int *p; 43 | 44 | std::cout << "getTypeName(p): " << getTypeName(p) << '\n'; 45 | std::cout << "getTypeName2(p): " << getTypeName2(p) << '\n'; 46 | 47 | std::cout << '\n'; 48 | 49 | } 50 | -------------------------------------------------------------------------------- /source/doubleFree.cpp: -------------------------------------------------------------------------------- 1 | // doubleFree.cpp 2 | 3 | #include 4 | 5 | class BigArray { 6 | 7 | public: 8 | BigArray(std::size_t len): len_(len), data_(new int[len]) {} 9 | 10 | ~BigArray(){ 11 | delete[] data_; 12 | } 13 | 14 | private: 15 | size_t len_; 16 | int* data_; 17 | }; 18 | 19 | int main(){ 20 | 21 | BigArray bigArray1(1000); 22 | 23 | BigArray bigArray2(1000); 24 | 25 | bigArray2 = bigArray1; 26 | 27 | } 28 | 29 | 30 | -------------------------------------------------------------------------------- /source/enable_if.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | template::value, T>::type= 0> 6 | T gcd(T a, T b) { 7 | if( b == 0 ){ return a; } 8 | else{ 9 | return gcd(b, a % b); 10 | } 11 | } 12 | 13 | int main() { 14 | 15 | std::cout << '\n'; 16 | 17 | std::cout << "gcd(100, 10)= " << gcd(100, 10) << '\n'; 18 | std::cout << "gcd(3.5, 4)= " << gcd(3.5, 4.0) << '\n'; 19 | 20 | std::cout << '\n'; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /source/enumChecksRange.cpp: -------------------------------------------------------------------------------- 1 | enum struct Color: char { 2 | red = 127, 3 | blue, 4 | green 5 | }; 6 | 7 | int main() { 8 | 9 | Color color{Color::green}; 10 | 11 | } 12 | -------------------------------------------------------------------------------- /source/equalityOperator.cpp: -------------------------------------------------------------------------------- 1 | class MyInt { 2 | int num; 3 | public: 4 | explicit MyInt(int n): num(n) {}; 5 | friend bool operator==(const MyInt& lhs, const MyInt& rhs) noexcept { 6 | return lhs.num == rhs.num; 7 | } 8 | friend bool operator==(int lhs, const MyInt& rhs) noexcept { 9 | return lhs == rhs.num; 10 | } 11 | friend bool operator==(const MyInt& lhs, int rhs) noexcept { 12 | return lhs.num == rhs; 13 | } 14 | }; 15 | 16 | int main() { 17 | MyInt(5) == 5; 18 | 5 == MyInt(5); 19 | } 20 | -------------------------------------------------------------------------------- /source/equalityOperatorHierarchy.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct Base { 4 | std::string name; 5 | int number; 6 | virtual bool operator == (const Base& a) const { 7 | return name == a.name && number == a.number; 8 | } 9 | }; 10 | 11 | struct Derived: Base { 12 | char character; 13 | virtual bool operator == (const Derived& a) const { 14 | return name == a.name && 15 | number == a.number && 16 | character == a.character; 17 | } 18 | }; 19 | 20 | int main() { 21 | 22 | Base b; 23 | Base& base = b; 24 | Derived d; 25 | Derived& derived = d; 26 | 27 | base == derived; // compares name and number, ignores derived's character 28 | derived == base; // error: no == defined 29 | Derived derived2; 30 | derived == derived2; // compares, name, number, and character 31 | Base& base2 = derived2; 32 | base2 == derived; // compares name and number, but 33 | // ignores derived2's and derived's character 34 | 35 | } 36 | -------------------------------------------------------------------------------- /source/factorial.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | template 4 | struct Factorial { 5 | static int const value = N * Factorial::value; 6 | }; 7 | 8 | template <> 9 | struct Factorial<1> { 10 | static int const value = 1; 11 | }; 12 | 13 | int main() { 14 | 15 | std::cout << '\n'; 16 | 17 | std::cout << "Factorial<5>::value: " << Factorial<5>::value << '\n'; 18 | std::cout << "Factorial<10>::value: " << Factorial<10>::value << '\n'; 19 | 20 | std::cout << '\n'; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /source/foldExpressions.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | template 4 | auto sum(Args... args) { 5 | return (... + args); 6 | } 7 | 8 | int main() { 9 | 10 | std::cout << "sum(5): " << sum(5) << '\n'; 11 | std::cout << "sum(1, 2, 3): " << sum(1, 2, 3) << '\n'; 12 | std::cout << "sum(1, 2, 3, 4): " << sum(1, 2, 3, 4) << '\n'; 13 | std::cout << "sum(1, 2, 3.5): " << sum(1, 2, 3.5) << '\n'; 14 | 15 | } 16 | -------------------------------------------------------------------------------- /source/forwarding.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | template 5 | T create(T1&& ... t1) { 6 | return T(std::forward(t1)...); 7 | } 8 | 9 | struct MyType { 10 | MyType(int, double, bool){} 11 | }; 12 | 13 | int main() { 14 | 15 | // lvalue 16 | int five=5; 17 | int myFive= create(five); 18 | 19 | // rvalues 20 | int myFive2= create(5); 21 | 22 | // no arguments 23 | int myZero= create(); 24 | 25 | // three arguments; (lvalue, rvalue, rvalue) 26 | MyType myType = create(myZero, 5.5, true); 27 | 28 | } 29 | 30 | -------------------------------------------------------------------------------- /source/functionObjects.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | bool byLessLength(const std::string& f, const std::string& s) { 9 | return f.size() < s.size(); 10 | } 11 | 12 | class ByGreaterLength { 13 | public: 14 | bool operator()(const std::string& f, const std::string& s) const { 15 | return f.size() > s.size(); 16 | } 17 | }; 18 | 19 | int main() { 20 | 21 | std::vector myStrVec = {"523345", "4336893456", "7234", 22 | "564", "199", "433", "2435345"}; 23 | 24 | std::cout << '\n'; 25 | 26 | std::cout << "Ascending by length with a function \n"; 27 | std::sort(myStrVec.begin(), myStrVec.end(), byLessLength); 28 | for (const auto& str: myStrVec) std::cout << str << " "; 29 | std::cout << "\n\n"; 30 | 31 | std::cout << "Descending by length with a function object \n"; 32 | std::sort(myStrVec.begin(), myStrVec.end(), ByGreaterLength()); 33 | for (const auto& str: myStrVec) std::cout << str << " "; 34 | std::cout << "\n\n"; 35 | 36 | std::cout << "Ascending by length with a lambda \n"; 37 | std::sort(myStrVec.begin(), myStrVec.end(), 38 | [](const std::string& f, const std::string& s){ 39 | return f.size() < s.size(); 40 | }); 41 | for (const auto& str: myStrVec) std::cout << str << " "; 42 | 43 | std::cout << "\n\n"; 44 | 45 | } 46 | -------------------------------------------------------------------------------- /source/functionOverloading.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void print(int) { 4 | std::cout << "int" << '\n'; 5 | } 6 | 7 | void print(double) { 8 | std::cout << "double" << '\n'; 9 | } 10 | 11 | void print(const char*) { 12 | std::cout << "const char* " << '\n'; 13 | } 14 | 15 | void print(int, double, const char*) { 16 | std::cout << "int, double, const char* " << '\n'; 17 | } 18 | 19 | 20 | int main() { 21 | 22 | std::cout << '\n'; 23 | 24 | print(10); 25 | print(10.10); 26 | print("ten"); 27 | print(10, 10.10, "ten"); 28 | 29 | std::cout << '\n'; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /source/functionTemplateSpecialization.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | template 5 | std::string getTypeName(T) { 6 | return "unknown type"; 7 | } 8 | 9 | template <> 10 | std::string getTypeName(int) { 11 | return "int"; 12 | } 13 | 14 | std::string getTypeName(double) { 15 | return "double"; 16 | } 17 | 18 | int main() { 19 | 20 | std::cout << '\n'; 21 | 22 | std::cout << "getTypeName(true): " << getTypeName(true) << '\n'; 23 | std::cout << "getTypeName(4711): " << getTypeName(4711) << '\n'; 24 | std::cout << "getTypeName(3.14): " << getTypeName(3.14) << '\n'; 25 | 26 | std::cout << '\n'; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /source/gcd.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | constexpr int gcd(int a, int b) { 4 | while (b != 0){ 5 | auto t = b; 6 | b = a % b; 7 | a = t; 8 | } 9 | return a; 10 | } 11 | 12 | int main() { 13 | 14 | std::cout << '\n'; 15 | 16 | constexpr auto res1 = gcd(121, 11); 17 | std::cout << "gcd(121, 11) = " << res1 << '\n'; 18 | 19 | auto val = 121; 20 | auto res2 = gcd(val, 11); 21 | std::cout << "gcd(val, 11) = " << res2 << '\n'; 22 | 23 | std::cout << '\n'; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /source/gcd2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | template 5 | T gcd(T a, T b) { 6 | static_assert(std::is_integral::value, "T should be an integral type!"); 7 | if( b == 0 ){ return a; } 8 | else{ 9 | return gcd(b, a % b); 10 | } 11 | } 12 | 13 | int main() { 14 | 15 | std::cout << gcd(100, 33) << '\n'; 16 | std::cout << gcd(3.5,4.0) << '\n'; 17 | std::cout << gcd("100","10") << '\n'; 18 | 19 | } 20 | -------------------------------------------------------------------------------- /source/genericArray.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | template 5 | class Array { 6 | public: 7 | Array()= default; 8 | std::size_t getSize() const{ 9 | return N; 10 | } 11 | private: 12 | T elem[N]; 13 | }; 14 | 15 | int main(){ 16 | 17 | Array arr1; 18 | std::cout << "arr1.getSize(): " << arr1.getSize() << '\n'; 19 | 20 | Array arr2; 21 | std::cout << "arr2.getSize(): " << arr2.getSize() << '\n'; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /source/genericArrayInheritance.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class ArrayBase { 5 | protected: 6 | ArrayBase(std::size_t n): size(n) {} 7 | std::size_t getSize() const { 8 | return size; 9 | }; 10 | private: 11 | std::size_t size; 12 | }; 13 | 14 | template 15 | class Array: private ArrayBase { 16 | public: 17 | Array(): ArrayBase(N){} 18 | std::size_t getSize() const { 19 | return ArrayBase::getSize(); 20 | } 21 | private: 22 | T data[N]; 23 | }; 24 | 25 | 26 | int main() { 27 | 28 | Array arr1; 29 | std::cout << "arr1.getSize(): " << arr1.getSize() << '\n'; 30 | 31 | Array arr2; 32 | std::cout << "arr2.getSize(): " << arr2.getSize() << '\n'; 33 | 34 | } 35 | -------------------------------------------------------------------------------- /source/gslCheck.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include 4 | 5 | void f(int* p, int count) { 6 | } 7 | 8 | void f2(int* p) { 9 | int x = *p; 10 | } 11 | 12 | int main() { 13 | 14 | // Break of type safety 15 | // use of a c-cast 16 | double d = 2; 17 | auto p = (long*)&d; 18 | auto q = (long long*)&d; 19 | 20 | // Break of bounds safety 21 | // array to pointer decay 22 | int myArray[100]; 23 | f(myArray, 100); 24 | 25 | // Break of Lifetime Safety 26 | // a is not valid 27 | int* a = new int; 28 | delete a; 29 | f2(a); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /source/gslCheckSuppress.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include 4 | 5 | void f(int* p, int count) { 6 | } 7 | 8 | int main() { 9 | 10 | int myArray[100]; 11 | 12 | // Break of bounds safety 13 | [[gsl::suppress(bounds.3)]] { // suppress warning 14 | f(myArray, 100); 15 | } 16 | 17 | f(myArray, 100); // warning 18 | 19 | } 20 | -------------------------------------------------------------------------------- /source/immortal.cpp: -------------------------------------------------------------------------------- 1 | class Immortal { 2 | public: 3 | ~Immortal() = delete; // do not allow destruction 4 | }; 5 | 6 | int main() { 7 | Immortal im; 8 | Immortal* pIm = new Immortal; 9 | 10 | delete pIm; 11 | } 12 | -------------------------------------------------------------------------------- /source/implicitConversion.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct MyHouse { 5 | MyHouse() = default; 6 | explicit MyHouse(const std::string& fam): family(fam) {} 7 | 8 | operator bool(){ return not family.empty(); } 9 | // explicit operator bool(){ return not family.empty(); } 10 | 11 | std::string family = ""; 12 | }; 13 | 14 | int main() { 15 | 16 | std::cout << std::boolalpha << '\n'; 17 | 18 | MyHouse firstHouse; 19 | if (not firstHouse) { 20 | std::cout << "firstHouse is not sold." << '\n'; 21 | } 22 | 23 | MyHouse secondHouse("grimm"); 24 | if (secondHouse) { 25 | std::cout << "Grimm bought secondHouse." << '\n'; 26 | } 27 | 28 | std::cout << '\n'; 29 | 30 | int myNewHouse = firstHouse + secondHouse; 31 | int myNewHouse2 = (20 * firstHouse - 10 * secondHouse) / secondHouse; 32 | 33 | std::cout << "myNewHouse: " << myNewHouse << '\n'; 34 | std::cout << "myNewHouse2: " << myNewHouse2 << '\n'; 35 | 36 | std::cout << '\n'; 37 | 38 | } 39 | -------------------------------------------------------------------------------- /source/initialisationAssignment.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class MyVal { 4 | public: 5 | MyVal(int i) { myInt = i; }; 6 | MyVal(double d): myDoub(d) {}; 7 | private: 8 | int myInt{}; 9 | double myDoub{}; 10 | }; 11 | 12 | int main() { 13 | 14 | std::cout << '\n'; 15 | 16 | MyVal myValInt(5); 17 | MyVal myValDou(5.5); 18 | 19 | std::cout << '\n'; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /source/isSmaller.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class Account { 4 | public: 5 | Account() = default; 6 | Account(double b): balance(b) {} 7 | private: 8 | double balance{0.0}; 9 | }; 10 | 11 | template 12 | bool isSmaller(T fir, T sec) { 13 | return fir < sec; 14 | } 15 | 16 | int main() { 17 | 18 | std::cout << std::boolalpha << '\n'; 19 | 20 | double firDoub{}; 21 | double secDoub{2014.0}; 22 | 23 | std::cout << "isSmaller(firDoub, secDoub): " 24 | << isSmaller(firDoub, secDoub) << '\n'; 25 | 26 | Account firAcc{}; 27 | Account secAcc{2014.0}; 28 | 29 | std::cout << "isSmaller(firAcc, secAcc): " 30 | << isSmaller(firAcc, secAcc) << '\n'; 31 | 32 | std::cout << '\n'; 33 | 34 | } 35 | -------------------------------------------------------------------------------- /source/lambdaFunctionCapture.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | auto makeLambda() { 6 | const std::string val = "on stack created"; 7 | return [&val]{return val;}; 8 | } 9 | 10 | int main() { 11 | 12 | auto bad = makeLambda(); 13 | std::cout << bad(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /source/lifecycle.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void initDevice(const char* mess) { 4 | printf("\n\nINIT: %s\n",mess); 5 | } 6 | 7 | void work(const char* mess) { 8 | printf("WORKING: %s",mess); 9 | } 10 | 11 | void shutDownDevice(const char* mess) { 12 | printf("\nSHUT DOWN: %s\n\n",mess); 13 | } 14 | 15 | int main(void) { 16 | 17 | initDevice("DEVICE 1"); 18 | work("DEVICE1"); 19 | { 20 | initDevice("DEVICE 2"); 21 | work("DEVICE2"); 22 | shutDownDevice("DEVICE 2"); 23 | } 24 | work("DEVICE 1"); 25 | shutDownDevice("DEVICE 1"); 26 | 27 | return 0; 28 | 29 | } 30 | -------------------------------------------------------------------------------- /source/lifecycle.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class Device { 5 | public: 6 | Device(const std::string& res):resource(res) { 7 | std::cout << "\nINIT: " << resource << ".\n"; 8 | } 9 | void work() const { 10 | std::cout << "WORKING: " << resource << '\n'; 11 | } 12 | ~Device() { 13 | std::cout << "SHUT DOWN: "<< resource << ".\n\n"; 14 | } 15 | private: 16 | const std::string resource; 17 | }; 18 | 19 | int main() { 20 | 21 | Device resGuard1{"DEVICE 1"}; 22 | resGuard1.work(); 23 | 24 | { 25 | Device resGuard2{"DEVICE 2"}; 26 | resGuard2.work(); 27 | } 28 | resGuard1.work(); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /source/lifetimeSemantic.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::cout; 5 | 6 | void asSmartPointerGood(std::shared_ptr& shr) { 7 | cout << "asSmartPointerGood \n"; 8 | cout << " shr.use_count(): " << shr.use_count() << '\n'; 9 | shr.reset(new int(2011)); 10 | cout << " shr.use_count(): " << shr.use_count() << '\n'; 11 | cout << "asSmartPointerGood \n"; 12 | } 13 | 14 | void asSmartPointerBad(std::shared_ptr& shr) { 15 | cout << "asSmartPointerBad(sharedPtr2) \n"; 16 | *shr += 19; 17 | } 18 | 19 | int main() { 20 | 21 | cout << '\n'; 22 | 23 | auto sharedPtr1 = std::make_shared(1998); 24 | auto sharedPtr2 = sharedPtr1; 25 | cout << "sharedPtr1.use_count(): " << sharedPtr1.use_count() << '\n'; 26 | 27 | cout << '\n'; 28 | 29 | asSmartPointerGood(sharedPtr1); 30 | 31 | cout << '\n'; 32 | 33 | cout << "*sharedPtr1: " << *sharedPtr1 << '\n'; 34 | cout << "sharedPtr1.use_count(): " << sharedPtr1.use_count() << '\n'; 35 | 36 | cout << '\n'; 37 | 38 | cout << "*sharedPtr2: " << *sharedPtr2 << '\n'; 39 | cout << "sharedPtr2.use_count(): " << sharedPtr2.use_count() << '\n'; 40 | 41 | cout << '\n'; 42 | 43 | asSmartPointerBad(sharedPtr2); 44 | cout << "*sharedPtr2: " << *sharedPtr2 << '\n'; 45 | 46 | cout << '\n'; 47 | 48 | } 49 | -------------------------------------------------------------------------------- /source/lockGuardDeadlock.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | struct CriticalData { 7 | std::mutex mut; 8 | }; 9 | 10 | void deadLock(CriticalData& a, CriticalData& b) { 11 | 12 | std::lock_guard guard1(a.mut); 13 | std::cout << "Thread: " << std::this_thread::get_id() << '\n'; 14 | 15 | std::this_thread::sleep_for(std::chrono::milliseconds(1)); 16 | 17 | std::lock_guard guard2(b.mut); 18 | std::cout << "Thread: " << std::this_thread::get_id() << '\n'; 19 | 20 | // do something with a and b (critical region) 21 | } 22 | 23 | int main() { 24 | 25 | std::cout << '\n'; 26 | 27 | CriticalData c1; 28 | CriticalData c2; 29 | 30 | std::thread t1([&]{deadLock(c1, c2);}); 31 | std::thread t2([&]{deadLock(c2, c1);}); 32 | 33 | t1.join(); 34 | t2.join(); 35 | 36 | std::cout << '\n'; 37 | 38 | } 39 | -------------------------------------------------------------------------------- /source/macro.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define max(a, b) ((a) > (b)) ? (a) : (b) 4 | 5 | int main() { 6 | 7 | int a = 1, b = 2; 8 | printf("\nmax(a, b): %d\n", max(a, b)); 9 | printf("a = %d, b = %d\n", a, b); 10 | 11 | printf("\nmax(++a, ++b): %d\n", max(++a, ++b)); // (1) 12 | printf("a = %d, b = %d\n\n", a, b); // (2) 13 | 14 | } 15 | -------------------------------------------------------------------------------- /source/main.cpp: -------------------------------------------------------------------------------- 1 | #include "a.h" 2 | 3 | int main() { 4 | A myA; 5 | } 6 | -------------------------------------------------------------------------------- /source/makeUnique.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct MyType{ 4 | MyType(int, double, bool){}; 5 | }; 6 | 7 | int main(){ 8 | 9 | int lvalue{2020}; 10 | 11 | std::unique_ptr uniqZero = std::make_unique(); 12 | auto uniqEleven = std::make_unique(2011); 13 | auto uniqTwenty = std::make_unique(lvalue); 14 | auto uniqType = std::make_unique(lvalue, 3.14, true); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /source/mallocVersusNew.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Record { 5 | explicit Record(std::string na): name(na) {} 6 | std::string name; 7 | }; 8 | 9 | int main() { 10 | 11 | Record* p1 = static_cast(malloc(sizeof(Record))); 12 | std::cout << p1->name << '\n'; 13 | 14 | auto p2 = new Record("Record"); 15 | std::cout << p2->name << '\n'; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /source/memberDeclarationOrder.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class Foo { 4 | int m1; 5 | int m2; 6 | public: 7 | Foo(int x) :m2{x}, m1{++x} { // BAD: misleading initializer order 8 | std::cout << "m1: " << m1 << '\n'; 9 | std::cout << "m2: " << m2 << '\n'; 10 | } 11 | }; 12 | 13 | int main() { 14 | 15 | std::cout << '\n'; 16 | Foo foo(1); 17 | std::cout << '\n'; 18 | 19 | } 20 | -------------------------------------------------------------------------------- /source/memoryAccess.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | const int SIZE = 100'000'000; 13 | 14 | template 15 | void sumUp(T& t, const std::string& cont) { 16 | 17 | std::cout << std::fixed << std::setprecision(10); 18 | 19 | auto begin = std::chrono::steady_clock::now(); 20 | std::size_t res = std::accumulate(t.begin(), t.end(), 0LL); 21 | std::chrono::duration last = 22 | std::chrono::steady_clock::now() - begin; 23 | std::cout << cont << '\n'; 24 | std::cout << "time: " << last.count() << '\n'; 25 | std::cout << "res: " << res << '\n'; 26 | std::cout << '\n'; 27 | 28 | std::cout << '\n'; 29 | 30 | } 31 | 32 | int main() { 33 | 34 | std::cout << '\n'; 35 | 36 | std::random_device seed; 37 | std::mt19937 engine(seed()); 38 | std::uniform_int_distribution dist(0, 100); 39 | std::vector randNum; 40 | randNum.reserve(SIZE); 41 | for (int i = 0; i < SIZE; ++i){ 42 | randNum.push_back(dist(engine)); 43 | } 44 | 45 | { 46 | std::vector vec(randNum.begin(), randNum.end()); 47 | sumUp(vec,"std::vector"); 48 | } 49 | 50 | 51 | { 52 | std::dequedeq(randNum.begin(), randNum.end()); 53 | sumUp(deq,"std::deque"); 54 | } 55 | 56 | { 57 | std::listlst(randNum.begin(), randNum.end()); 58 | sumUp(lst,"std::list"); 59 | } 60 | 61 | { 62 | std::forward_listforwardLst(randNum.begin(), 63 | randNum.end()); 64 | sumUp(forwardLst,"std::forward_list"); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /source/mixSignedUnsigend.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | 5 | int x = -3; 6 | unsigned int y = 7; 7 | 8 | std::cout << x - y << '\n'; // 4294967286 9 | std::cout << x + y << '\n'; // 4 10 | std::cout << x * y << '\n'; // 4294967275 11 | std::cout << x / y << '\n'; // 613566756 12 | 13 | } 14 | -------------------------------------------------------------------------------- /source/modulo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(){ 5 | 6 | std::cout << '\n'; 7 | 8 | unsigned int max{100000}; 9 | unsigned short x{0}; 10 | std::size_t count{0}; 11 | while (x < max && count < 20) { 12 | std::cout << x << " "; 13 | x += 10000; 14 | ++count; 15 | } 16 | 17 | std::cout << "\n\n"; 18 | 19 | } 20 | -------------------------------------------------------------------------------- /source/mostVexingParse.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct MyInt { 4 | MyInt(int arg = 0): i(arg) {} 5 | int i; 6 | }; 7 | 8 | 9 | int main() { 10 | 11 | MyInt myInt(2011); 12 | MyInt myInt2{}; 13 | 14 | std::cout << myInt.i; 15 | std::cout << myInt2.i; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /source/mostVexingParseSolved.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct MyInt { 4 | MyInt(int arg = 0): i(arg) {} 5 | int i; 6 | }; 7 | 8 | 9 | int main() { 10 | 11 | MyInt myInt(2011); 12 | MyInt myInt2{}; 13 | 14 | std::cout << myInt.i; 15 | std::cout << myInt2.i; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /source/moveUniquePtr.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | void takeUniquePtr(std::unique_ptr uniqPtr) { 8 | std::cout << "*uniqPtr: " << *uniqPtr << '\n'; 9 | } 10 | 11 | int main() { 12 | 13 | std::cout << '\n'; 14 | 15 | auto uniqPtr1 = std::make_unique(2011); 16 | 17 | takeUniquePtr(std::move(uniqPtr1)); 18 | 19 | auto uniqPtr2 = std::make_unique(2014); 20 | auto uniqPtr3 = std::make_unique(2017); 21 | 22 | std::vector> vecUniqPtr {}; 23 | vecUniqPtr.push_back(std::move(uniqPtr2)); 24 | vecUniqPtr.push_back(std::move(uniqPtr3)); 25 | vecUniqPtr.push_back(std::make_unique(2020)); 26 | 27 | std::cout << '\n'; 28 | 29 | std::for_each(vecUniqPtr.begin(), vecUniqPtr.end(), 30 | [](std::unique_ptr& uniqPtr){ std::cout << *uniqPtr << '\n'; } ); 31 | 32 | std::cout << '\n'; 33 | 34 | } 35 | -------------------------------------------------------------------------------- /source/mutable.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct Immutable { 4 | mutable int val{12}; 5 | void canNotModify() const { 6 | val = 13; 7 | } 8 | }; 9 | 10 | int main() { 11 | 12 | std::cout << '\n'; 13 | 14 | const Immutable immu; 15 | std::cout << "val: " << immu.val << '\n'; 16 | immu.canNotModify(); 17 | std::cout << "val: " << immu.val << '\n'; 18 | 19 | std::cout << '\n'; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /source/myGuard.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | template 5 | class MyGuard { 6 | public: 7 | explicit MyGuard(T& m): myMutex(m) { 8 | std::cout << "lock" << '\n'; 9 | myMutex.lock(); 10 | } 11 | ~MyGuard() { 12 | myMutex.unlock(); 13 | std::cout << "unlock" << '\n'; 14 | } 15 | private: 16 | T& myMutex; 17 | }; 18 | 19 | int main() { 20 | 21 | std::cout << '\n'; 22 | 23 | std::mutex m; 24 | MyGuard {m}; 25 | std::cout << "CRITICAL SECTION" << '\n'; 26 | 27 | std::cout << '\n'; 28 | 29 | } 30 | -------------------------------------------------------------------------------- /source/nakedUnion.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | union Value { 4 | int i; 5 | double d; 6 | }; 7 | 8 | int main() { 9 | 10 | std::cout << '\n'; 11 | 12 | Value v; 13 | v.d = 987.654; 14 | std::cout << "v.d: " << v.d << '\n'; 15 | std::cout << "v.i: " << v.i << '\n'; 16 | 17 | std::cout << '\n'; 18 | 19 | v.i = 123; 20 | std::cout << "v.i: " << v.i << '\n'; 21 | std::cout << "v.d: " << v.d << '\n'; 22 | 23 | std::cout << '\n'; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /source/namespaceDirective.cpp: -------------------------------------------------------------------------------- 1 | // namespaceDirective.cpp 2 | 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | using namespace std::chrono; 8 | using namespace std::literals::chrono_literals; 9 | 10 | int main() { 11 | 12 | cout << '\n'; 13 | 14 | auto schoolHour = 45min; 15 | 16 | auto shortBreak = 300s; 17 | auto longBreak = 0.25h; 18 | 19 | auto schoolWay = 15min; 20 | auto homework = 2h; 21 | 22 | auto schoolDayInSec = 2 * schoolWay + 6 * schoolHour + 23 | 4 * shortBreak + longBreak + homework; 24 | 25 | cout << "School day in seconds: " << schoolDayInSec.count() << endl; 26 | 27 | duration> schoolDayInHours = schoolDayInSec; 28 | duration> schoolDayInMin = schoolDayInSec; 29 | duration> schoolDayInMilli = schoolDayInSec; 30 | 31 | cout << "School day in hours: " << schoolDayInHours.count() << endl; 32 | cout << "School day in minutes: " << schoolDayInMin.count() << endl; 33 | cout << "School day in milliseconds: " 34 | << schoolDayInMilli.count() << endl; 35 | 36 | cout << endl; 37 | 38 | } 39 | -------------------------------------------------------------------------------- /source/namespaceDirectiveRemoved.cpp: -------------------------------------------------------------------------------- 1 | // namespaceDirectiveRemoved.cpp 2 | 3 | #include 4 | #include 5 | 6 | using namespace std::literals::chrono_literals; 7 | 8 | int main() { 9 | 10 | std::cout << std::endl; 11 | 12 | auto schoolHour = 45min; 13 | 14 | auto shortBreak = 300s; 15 | auto longBreak = 0.25h; 16 | 17 | auto schoolWay = 15min; 18 | auto homework = 2h; 19 | 20 | auto schoolDayInSec = 2 * schoolWay + 6 * schoolHour + 21 | 4 * shortBreak + longBreak + homework; 22 | 23 | std::cout << "School day in seconds: " << schoolDayInSec.count() << std::endl; 24 | 25 | std::chrono::duration> schoolDayInHours = schoolDayInSec; 26 | std::chrono::duration> schoolDayInMin = schoolDayInSec; 27 | std::chrono::duration> schoolDayInMilli = schoolDayInSec; 28 | 29 | std::cout << "School day in hours: " << schoolDayInHours.count() << std::endl; 30 | std::cout << "School day in minutes: " << schoolDayInMin.count() << std::endl; 31 | std::cout << "School day in milliseconds: " 32 | << schoolDayInMilli.count() << std::endl; 33 | 34 | std::cout << std::endl; 35 | 36 | } 37 | -------------------------------------------------------------------------------- /source/narrowingConversion.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | 5 | char c1(999); 6 | char c2 = (999); 7 | std::cout << "c1: " << c1 << '\n'; 8 | std::cout << "c2: " << c2 << '\n'; 9 | 10 | int i1(3.14); 11 | int i2 = (3.14); 12 | std::cout << "i1: " << i1 << '\n'; 13 | std::cout << "i2: " << i2 << '\n'; 14 | 15 | } 16 | -------------------------------------------------------------------------------- /source/narrowingConversionSolved.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | 5 | char c1{999}; 6 | char c2 = {999}; 7 | std::cout << "c1: " << c1 << '\n'; 8 | std::cout << "c2: " << c2 << '\n'; 9 | 10 | int i1{3.14}; 11 | int i2 = {3.14}; 12 | std::cout << "i1: " << i1 << '\n'; 13 | std::cout << "i2: " << i2 << '\n'; 14 | 15 | } 16 | -------------------------------------------------------------------------------- /source/notGeneric.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | template 6 | void justIterate(const Cont& cont) { 7 | const auto itEnd = cont.end(); 8 | for (auto it = cont.begin(); it < itEnd; ++it) { 9 | // do something 10 | } 11 | } 12 | 13 | int main() { 14 | 15 | std::vector vecInt{1, 2, 3, 4, 5}; 16 | justIterate(vecInt); 17 | 18 | std::deque deqInt{1, 2, 3, 4, 5}; 19 | justIterate(deqInt); 20 | 21 | std::list listInt{1, 2, 3, 4, 5}; 22 | justIterate(listInt); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /source/nullPointer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | template 5 | void functionTemplate(P p) { 6 | int* a = p; 7 | } 8 | 9 | int main() { 10 | int* a = 0; 11 | int* b = NULL; 12 | int* c = nullptr; 13 | 14 | functionTemplate(0); 15 | functionTemplate(NULL); 16 | functionTemplate(nullptr); 17 | } 18 | -------------------------------------------------------------------------------- /source/overUnderflow.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | 6 | int a[0]; 7 | int n = 0; 8 | 9 | while (true){ 10 | if (!(n % 100)){ 11 | std::cout << "a[" << n << "] = " << a[n] 12 | << ", a[" << -n << "] = " << a[-n] << '\n'; 13 | } 14 | a[n] = n; 15 | a[-n] = -n; 16 | ++n; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /source/overflow.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | 6 | std::cout << '\n'; 7 | 8 | int max{100000}; 9 | short x{0}; 10 | std::size_t count{0}; 11 | while (x < max && count < 20) { 12 | std::cout << x << " "; 13 | x += 10000; 14 | ++count; 15 | } 16 | 17 | std::cout << "\n\n"; 18 | 19 | } 20 | -------------------------------------------------------------------------------- /source/overloadSet.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class Base { 4 | public: 5 | void func(int i) { std::cout << "Base::func(int) \n"; } 6 | void func(double d) { std::cout << "Base::func(double) \n"; } 7 | }; 8 | 9 | class Derived: public Base { 10 | public: 11 | void func(int i) { std::cout << "Derived::func(int) \n"; } 12 | }; 13 | 14 | int main() { 15 | 16 | std::cout << '\n'; 17 | 18 | Derived der; 19 | der.func(2011); 20 | der.func(2020.5); 21 | 22 | std::cout << '\n'; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /source/overrider.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class Base { 4 | public: 5 | virtual int multiply(int value, int factor = 2) = 0; 6 | }; 7 | 8 | class Derived : public Base { 9 | public: 10 | int multiply(int value, int factor = 10) override { 11 | return factor * value; 12 | } 13 | }; 14 | 15 | int main() { 16 | 17 | std::cout << '\n'; 18 | 19 | Derived d; 20 | Base& b = d; 21 | 22 | std::cout << "b.multiply(10): " << b.multiply(10) << '\n'; 23 | std::cout << "d.multiply(10): " << d.multiply(10) << '\n'; 24 | 25 | std::cout << '\n'; 26 | 27 | } 28 | -------------------------------------------------------------------------------- /source/ownershipSemantic.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | class MyInt { 6 | public: 7 | explicit MyInt(int val): myInt(val){} 8 | ~MyInt() { 9 | std::cout << myInt << '\n'; 10 | } 11 | private: 12 | int myInt; 13 | }; 14 | 15 | void funcCopy(MyInt myInt) {} 16 | void funcPtr(MyInt* myInt) {} 17 | void funcRef(MyInt& myInt) {} 18 | void funcUniqPtr(std::unique_ptr myInt) {} 19 | void funcSharedPtr(std::shared_ptr myInt) {} 20 | 21 | int main() { 22 | 23 | std::cout << '\n'; 24 | 25 | std::cout << "=== Begin" << '\n'; 26 | 27 | MyInt myInt{1998}; 28 | MyInt* myIntPtr = &myInt; 29 | MyInt& myIntRef = myInt; 30 | auto uniqPtr = std::make_unique(2011); 31 | auto sharedPtr = std::make_shared(2014); 32 | 33 | funcCopy(myInt); 34 | funcPtr(myIntPtr); 35 | funcRef(myIntRef); 36 | funcUniqPtr(std::move(uniqPtr)); 37 | funcSharedPtr(sharedPtr); 38 | 39 | std::cout << "==== End" << '\n'; 40 | 41 | std::cout << '\n'; 42 | 43 | } 44 | -------------------------------------------------------------------------------- /source/power.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int power(int m, int n) { 4 | int r = 1; 5 | for(int k = 1; k <= n; ++k) r *= m; 6 | return r; 7 | } 8 | 9 | template 10 | struct Power { 11 | static int const value = m * Power::value; 12 | }; 13 | 14 | template 15 | struct Power { 16 | static int const value = 1; 17 | }; 18 | 19 | int main() { 20 | 21 | std::cout << '\n'; 22 | 23 | std::cout << "power(2, 10)= " << power(2, 10) << '\n'; 24 | std::cout << "Power<2,10>::value= " << Power<2, 10>::value << '\n'; 25 | 26 | std::cout << '\n'; 27 | } 28 | -------------------------------------------------------------------------------- /source/powerHybrid.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | template 4 | int power(int m) { 5 | return m * power(m); 6 | } 7 | 8 | template<> 9 | int power<1>(int m) { 10 | return m; 11 | } 12 | 13 | template<> 14 | int power<0>(int m) { 15 | return 1; 16 | } 17 | 18 | int main() { 19 | 20 | std::cout << '\n'; 21 | 22 | std::cout << "power<10>(2): " << power<10>(2) << '\n'; 23 | 24 | std::cout << '\n'; 25 | 26 | auto power2 = power<2>; 27 | 28 | for (int i = 0; i <= 10; ++i){ 29 | std::cout << "power2(" << i << ")= " 30 | << power2(i) << '\n'; 31 | } 32 | 33 | std::cout << '\n'; 34 | 35 | } 36 | -------------------------------------------------------------------------------- /source/primaryTypeCategories.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct A { 5 | int a; 6 | int f(int) { return 2011; } 7 | }; 8 | 9 | enum E { 10 | e= 1, 11 | }; 12 | 13 | union U { 14 | int u; 15 | }; 16 | 17 | 18 | int main() { 19 | 20 | using namespace std; 21 | 22 | cout << boolalpha << '\n'; 23 | 24 | cout << is_void::value << '\n'; 25 | cout << is_integral::value << '\n'; 26 | cout << is_floating_point::value << '\n'; 27 | cout << is_array::value << '\n'; 28 | cout << is_pointer::value << '\n'; 29 | cout << is_null_pointer::value << '\n'; 30 | cout << is_member_object_pointer::value << '\n'; 31 | cout << is_member_function_pointer::value << '\n'; 32 | cout << is_enum::value << '\n'; 33 | cout << is_union::value << '\n'; 34 | cout << is_class::value << '\n'; 35 | cout << is_function::value << '\n'; 36 | cout << is_lvalue_reference::value << '\n'; 37 | cout << is_rvalue_reference::value << '\n'; 38 | 39 | cout << '\n'; 40 | 41 | } 42 | -------------------------------------------------------------------------------- /source/printfIostreamsUndefinedBehavior.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | int main() { 6 | 7 | printf("\n"); 8 | 9 | printf("2011: %d\n",2011); 10 | printf("3.1416: %d\n",3.1416); 11 | printf("\"2011\": %d\n","2011"); 12 | // printf("%s\n",2011); // segmentation fault 13 | 14 | std::cout << '\n'; 15 | std::cout << "2011: " << 2011 << '\n'; 16 | std::cout << "3.146: " << 3.1416 << '\n'; 17 | std::cout << "\"2011\": " << "2011" << '\n'; 18 | 19 | std::cout << '\n'; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /source/promiseFutureException.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | struct Div { 8 | void operator()(std::promise intPromise, int a, int b) const { 9 | try { 10 | if (b == 0) { 11 | std::string err = "Illegal division by zero: " + 12 | std::to_string(a) + "/" + std::to_string(b); 13 | throw std::runtime_error(err); 14 | } 15 | intPromise.set_value(a / b); 16 | } 17 | catch ( ... ) { 18 | intPromise.set_exception(std::current_exception()); 19 | } 20 | } 21 | }; 22 | 23 | void executeDivision(int nom, int denom) { 24 | std::promise divPromise; 25 | std::future divResult= divPromise.get_future(); 26 | 27 | Div div; 28 | std::thread divThread(div,std::move(divPromise), nom, denom); 29 | 30 | // get the result or the exception 31 | try { 32 | std::cout << nom << "/" << denom << " = " << divResult.get() << '\n'; 33 | } 34 | catch (std::runtime_error& e){ 35 | std::cout << e.what() << '\n'; 36 | } 37 | 38 | divThread.join(); 39 | } 40 | 41 | int main() { 42 | 43 | std::cout << '\n'; 44 | 45 | executeDivision(20, 0); 46 | executeDivision(20, 10); 47 | 48 | std::cout << '\n'; 49 | 50 | } 51 | -------------------------------------------------------------------------------- /source/promiseFutureSynchronize.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void waitingForWork(std::future fut) { 6 | std::cout << "Waiting " << '\n'; 7 | fut.wait(); 8 | std::cout << "Running " << '\n'; 9 | } 10 | 11 | void setDataReady(std::promise prom) { 12 | std::cout << "Data prepared" << '\n'; 13 | prom.set_value(); 14 | } 15 | 16 | int main() { 17 | 18 | std::cout << '\n'; 19 | 20 | std::promise sendReady; 21 | auto fut = sendReady.get_future(); 22 | 23 | std::thread t1(waitingForWork, std::move(fut)); 24 | std::thread t2(setDataReady, std::move(sendReady)); 25 | 26 | t1.join(); 27 | t2.join(); 28 | 29 | std::cout << '\n'; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /source/raii.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | class ResourceGuard { 6 | public: 7 | explicit ResourceGuard(const std::string& res):resource(res){ 8 | std::cout << "Acquire the " << resource << "." << '\n'; 9 | } 10 | ~ResourceGuard(){ 11 | std::cout << "Release the "<< resource << "." << '\n'; 12 | } 13 | private: 14 | std::string resource; 15 | }; 16 | 17 | int main() { 18 | 19 | std::cout << '\n'; 20 | 21 | ResourceGuard resGuard1{"memoryBlock1"}; 22 | 23 | std::cout << "\nBefore local scope" << '\n'; 24 | { 25 | ResourceGuard resGuard2{"memoryBlock2"}; 26 | } 27 | std::cout << "After local scope" << '\n'; 28 | 29 | std::cout << '\n'; 30 | 31 | 32 | std::cout << "\nBefore try-catch block" << '\n'; 33 | try { 34 | ResourceGuard resGuard3{"memoryBlock3"}; 35 | throw std::bad_alloc(); 36 | } 37 | catch (const std::bad_alloc& e) { 38 | std::cout << e.what(); 39 | } 40 | std::cout << "\nAfter try-catch block" << '\n'; 41 | 42 | std::cout << '\n'; 43 | 44 | } 45 | -------------------------------------------------------------------------------- /source/records.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | struct Rec { 8 | std::string name; 9 | std::string addr; 10 | int id; 11 | }; 12 | 13 | int main() { 14 | 15 | std::cout << '\n'; 16 | 17 | std::vector vr{ {"Grimm", "Munich", 1}, 18 | {"huber", "Stuttgart", 2}, 19 | {"Smith", "Rottenburg", 3}, 20 | {"black", "Hanover", 4} }; 21 | 22 | std::string name = "smith"; 23 | 24 | auto rec = std::find_if(vr.begin(), vr.end(), [&name](Rec& r) { 25 | if (r.name.size() != name.size()) return false; 26 | for (std::string::size_type i = 0; i < r.name.size(); ++i) { 27 | if (std::tolower(r.name[i]) != std::tolower(name[i])) return false; 28 | } 29 | return true; 30 | }); 31 | 32 | if (rec != vr.end()) { 33 | std::cout << rec->name << ", " << rec->addr << ", " << rec->id << '\n'; 34 | } 35 | 36 | std::cout << '\n'; 37 | 38 | } 39 | -------------------------------------------------------------------------------- /source/relaxedSemantic.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | std::atomic x{0}; 6 | std::atomic y{0}; 7 | 8 | void writing(){ 9 | x.store(2000, std::memory_order_relaxed); 10 | y.store(11, std::memory_order_relaxed); 11 | } 12 | 13 | void reading(){ 14 | std::cout << y.load(std::memory_order_relaxed) << " "; 15 | std::cout << x.load(std::memory_order_relaxed) << '\n'; 16 | } 17 | 18 | int main(){ 19 | std::thread thread1(writing); 20 | std::thread thread2(reading); 21 | thread1.join(); 22 | thread2.join(); 23 | } 24 | -------------------------------------------------------------------------------- /source/removeConst.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | template 5 | struct removeConst { 6 | using type = T; 7 | }; 8 | 9 | template 10 | struct removeConst { 11 | using type = T; 12 | }; 13 | 14 | using std::boolalpha; 15 | using std::cout; 16 | using std::is_same; 17 | 18 | int main() { 19 | 20 | cout << boolalpha; 21 | 22 | cout << is_same::type>::value << '\n'; // true 23 | cout << is_same::type>::value << '\n'; // true 24 | 25 | } 26 | -------------------------------------------------------------------------------- /source/returnPair.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() { 6 | 7 | std::cout << '\n'; 8 | 9 | std::set mySet; 10 | 11 | std::set::iterator iter; 12 | bool inserted = false; 13 | std::tie(iter, inserted) = mySet.insert(2011); // (1) 14 | if (inserted) std::cout << "2011 was inserted successfully\n"; 15 | 16 | auto [iter2, inserted2] = mySet.insert(2017); // (2) 17 | if (inserted2) std::cout << "2017 was inserted successfully\n"; 18 | 19 | std::cout << '\n'; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /source/returnRvalueReference.cpp: -------------------------------------------------------------------------------- 1 | int&& returnRvalueReference() { 2 | return int{}; 3 | } 4 | 5 | int main(){ 6 | 7 | auto myInt = returnRvalueReference(); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /source/sclice.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Base { 5 | virtual std::string getName() const { 6 | return "Base"; 7 | } 8 | }; 9 | 10 | struct Derived : Base { 11 | std::string getName() const override { 12 | return "Derived"; 13 | } 14 | }; 15 | 16 | int main() { 17 | 18 | std::cout << '\n'; 19 | 20 | Base b; 21 | std::cout << "b.getName(): " << b.getName() << '\n'; 22 | 23 | Derived d; 24 | std::cout << "d.getName(): " << d.getName() << '\n'; 25 | 26 | Base b1 = d; 27 | std::cout << "b1.getName(): " << b1.getName() << '\n'; 28 | 29 | Base& b2 = d; 30 | std::cout << "b2.getName(): " << b2.getName() << '\n'; 31 | 32 | Base* b3 = new Derived; 33 | std::cout << "b3->getName(): " << b3->getName() << '\n'; 34 | 35 | std::cout << '\n'; 36 | 37 | } 38 | -------------------------------------------------------------------------------- /source/scopedEnum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | enum class ColorScoped { 4 | red, 5 | blue, 6 | green 7 | }; 8 | 9 | void useMe(ColorScoped color) { 10 | switch(color) { 11 | case ColorScoped::red: 12 | std::cout << "ColorScoped::red" << '\n'; 13 | break; 14 | case ColorScoped::blue: 15 | std::cout << "ColorScoped::blue" << '\n'; 16 | break; 17 | case ColorScoped::green: 18 | std::cout << "ColorScoped::green" << '\n'; 19 | break; 20 | } 21 | } 22 | 23 | 24 | int main() { 25 | 26 | std::cout << static_cast(ColorScoped::red) << '\n'; // 0 27 | std::cout << static_cast(ColorScoped::green) << '\n'; // 2 28 | 29 | ColorScoped color{ColorScoped::red}; 30 | useMe(color); // ColorScoped::red 31 | 32 | } 33 | -------------------------------------------------------------------------------- /source/semiRegular.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | 6 | std::cout << std::boolalpha << '\n'; 7 | 8 | std::cout << "std::is_default_constructible::value: " 9 | << std::is_default_constructible::value << '\n'; 10 | std::cout << "std::is_copy_constructible::value: " 11 | << std::is_copy_constructible::value << '\n'; 12 | std::cout << "std::is_copy_assignable::value: " 13 | << std::is_copy_assignable::value << '\n'; 14 | std::cout << "std::is_move_constructible::value: " 15 | << std::is_move_constructible::value << '\n'; 16 | std::cout << "std::is_move_assignable::value: " 17 | << std::is_move_assignable::value << '\n'; 18 | std::cout << "std::is_destructible::value: " 19 | << std::is_destructible::value << '\n'; 20 | std::cout << '\n'; 21 | std::cout << "std::is_swappable::value: " 22 | << std::is_swappable::value << '\n'; 23 | 24 | std::cout << '\n'; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /source/sequentialConsistency.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | std::atomic x{0}; 6 | std::atomic y{0}; 7 | 8 | void writing(){ 9 | x.store(2000); 10 | y.store(11); 11 | } 12 | 13 | void reading(){ 14 | std::cout << y.load() << " "; 15 | std::cout << x.load() << '\n'; 16 | } 17 | 18 | int main(){ 19 | std::thread thread1(writing); 20 | std::thread thread2(reading); 21 | thread1.join(); 22 | thread2.join(); 23 | } 24 | -------------------------------------------------------------------------------- /source/shadow.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | int shadow(bool cond) { 5 | int d = 0; 6 | if (cond) { 7 | d = 1; 8 | } 9 | else { 10 | int d = 2; // declare a local scoped d; 11 | // hiding d of the parent scope 12 | d = 3; 13 | } 14 | return d; 15 | } 16 | 17 | int main() { 18 | 19 | std::cout << '\n'; 20 | 21 | std::cout << "shadow(true): " << shadow(true) << '\n'; 22 | std::cout << "shadow(false): " << shadow(false) << '\n'; 23 | 24 | std::cout << '\n'; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /source/shadowClass.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Base { 5 | void shadow(std::string) { 6 | std::cout << "Base::shadow" << '\n'; 7 | } 8 | }; 9 | 10 | struct Derived: Base { 11 | using Base::shadow; 12 | void shadow(int) { 13 | std::cout << "Derived::shadow" << '\n'; 14 | } 15 | }; 16 | 17 | int main() { 18 | 19 | std::cout << '\n'; 20 | 21 | Derived derived; 22 | 23 | derived.shadow(std::string{}); 24 | derived.shadow(int{}); 25 | 26 | std::cout << '\n'; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /source/signedTypes.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | template 4 | T subtract(T x, T2 y) { 5 | return x - y; 6 | } 7 | 8 | int main() { 9 | 10 | int s = 5; 11 | unsigned int us = 5; 12 | std::cout << subtract(s, 7) << '\n'; // -2 13 | std::cout << subtract(us, 7u) << '\n'; // 4294967294 14 | std::cout << subtract(s, 7u) << '\n'; // -2 15 | std::cout << subtract(us, 7) << '\n'; // 4294967294 16 | std::cout << subtract(s, us + 2) << '\n'; // -2 17 | std::cout << subtract(us, s + 2) << '\n'; // 4294967294 18 | 19 | 20 | } 21 | -------------------------------------------------------------------------------- /source/singleton.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class MySingleton { 4 | 5 | public: 6 | MySingleton(const MySingleton&)= delete; 7 | MySingleton& operator = (const MySingleton&)= delete; 8 | 9 | static MySingleton* getInstance() { 10 | if ( !instance ){ 11 | instance= new MySingleton(); 12 | } 13 | return instance; 14 | } 15 | 16 | private: 17 | static MySingleton* instance; 18 | MySingleton()= default; 19 | ~MySingleton()= default; 20 | }; 21 | 22 | MySingleton* MySingleton::instance= nullptr; 23 | 24 | 25 | int main() { 26 | 27 | std::cout << MySingleton::getInstance() << "\n"; 28 | std::cout << MySingleton::getInstance() << "\n"; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /source/singletonMeyers.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | constexpr auto tenMill = 10'000'000; 6 | 7 | class MySingleton { 8 | public: 9 | static MySingleton& getInstance() { 10 | static MySingleton instance; 11 | volatile int dummy{}; 12 | return instance; 13 | } 14 | private: 15 | MySingleton()= default; 16 | ~MySingleton()= default; 17 | MySingleton(const MySingleton&)= delete; 18 | MySingleton& operator = (const MySingleton&)= delete; 19 | }; 20 | 21 | std::chrono::duration getTime() { 22 | 23 | auto begin= std::chrono::system_clock::now(); 24 | for (size_t i = 0; i < tenMill; ++i) { 25 | MySingleton::getInstance(); 26 | } 27 | return std::chrono::system_clock::now() - begin; 28 | 29 | }; 30 | 31 | int main() { 32 | 33 | auto fut1 = std::async(std::launch::async,getTime); 34 | auto fut2 = std::async(std::launch::async,getTime); 35 | auto fut3 = std::async(std::launch::async,getTime); 36 | auto fut4 = std::async(std::launch::async,getTime); 37 | 38 | auto total = fut1.get() + fut2.get() + fut3.get() + fut4.get(); 39 | 40 | std::cout << total.count() << '\n'; 41 | 42 | } 43 | -------------------------------------------------------------------------------- /source/sizeof.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() { 6 | 7 | std::cout << '\n'; 8 | 9 | std::cout << "sizeof(int)= " << sizeof(int) << '\n'; 10 | 11 | std::cout << '\n'; 12 | 13 | int cArr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 14 | 15 | std::array cppArr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 16 | 17 | std::vector cppVec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 18 | 19 | std::cout << "sizeof(cArr)= " << sizeof(cArr) << '\n'; 20 | 21 | std::cout << "sizeof(cppArr)= " << sizeof(cppArr) << '\n'; 22 | 23 | 24 | 25 | std::cout << "sizeof(cppVec) = " << sizeof(cppVec) + sizeof(int) * cppVec.capacity() << '\n'; 26 | std::cout << " = sizeof(cppVec): " << sizeof(cppVec) << '\n'; 27 | std::cout << " + sizeof(int)* cppVec.capacity(): " << sizeof(int)* cppVec.capacity() << '\n'; 28 | 29 | std::cout << '\n'; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /source/slice.cpp: -------------------------------------------------------------------------------- 1 | struct Base { 2 | int base{1998}; 3 | }; 4 | 5 | struct Derived : Base { 6 | int derived{2011}; 7 | }; 8 | 9 | void needB(Base b) { 10 | // ... 11 | }; 12 | 13 | int main() { 14 | 15 | Derived d; 16 | Base b = d; 17 | Base b2(d); 18 | needB(d); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /source/sliceVirtuality.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Base { 5 | virtual std::string getName() const { 6 | return "Base"; 7 | } 8 | }; 9 | 10 | struct Derived : Base { 11 | std::string getName() const override { 12 | return "Derived"; 13 | } 14 | }; 15 | 16 | int main() { 17 | 18 | std::cout << '\n'; 19 | 20 | Base b; 21 | std::cout << "b.getName(): " << b.getName() << '\n'; 22 | 23 | Derived d; 24 | std::cout << "d.getName(): " << d.getName() << '\n'; 25 | 26 | Base b1 = d; 27 | std::cout << "b1.getName(): " << b1.getName() << '\n'; 28 | 29 | Base& b2 = d; 30 | std::cout << "b2.getName(): " << b2.getName() << '\n'; 31 | 32 | Base* b3 = new Derived; 33 | std::cout << "b3->getName(): " << b3->getName() << '\n'; 34 | 35 | std::cout << '\n'; 36 | 37 | } 38 | -------------------------------------------------------------------------------- /source/standaloneAllocation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct MyInt{ 5 | explicit MyInt(int myInt):i(myInt) {} 6 | ~MyInt() { 7 | std::cout << "Goodbye from " << i << '\n'; 8 | } 9 | int i; 10 | }; 11 | 12 | int main() { 13 | 14 | std::cout << '\n'; 15 | 16 | MyInt* myInt = new MyInt(2011); 17 | 18 | std::unique_ptr uniq1 = std::unique_ptr(myInt); 19 | std::unique_ptr uniq2 = std::unique_ptr(myInt); 20 | 21 | std::cout << '\n'; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /source/strange.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct Strange { 4 | 5 | Strange(): p(new int(2011)) {} 6 | 7 | // deep copy 8 | Strange(const Strange& a) : p(new int(*a.p)) {} 9 | 10 | // shallow copy 11 | // equivalent to Strange& operator = (const Strange&) = default; 12 | Strange& operator = (const Strange& a) { 13 | p = a.p; 14 | return *this; 15 | } 16 | 17 | int* p; 18 | 19 | }; 20 | 21 | int main() { 22 | 23 | std::cout << '\n'; 24 | 25 | std::cout << "Deep copy" << '\n'; 26 | 27 | Strange s1; 28 | Strange s2(s1); 29 | 30 | std::cout << "s1.p: " << s1.p << "; *s1.p: " << *s1.p << '\n'; 31 | std::cout << "s2.p: " << s2.p << "; *s2.p: " << *s2.p << '\n'; 32 | 33 | std::cout << "*s2.p = 2017" << '\n'; 34 | *s2.p = 2017; 35 | 36 | std::cout << "s1.p: " << s1.p << "; *s1.p: " << *s1.p << '\n'; 37 | std::cout << "s2.p: " << s2.p << "; *s2.p: " << *s2.p << '\n'; 38 | 39 | std::cout << '\n'; 40 | 41 | std::cout << "Shallow copy" << '\n'; 42 | 43 | Strange s3; 44 | s3 = s1; 45 | 46 | std::cout << "s1.p: " << s1.p << "; *s1.p: " << *s1.p << '\n'; 47 | std::cout << "s3.p: " << s3.p << "; *s3.p: " << *s3.p << '\n'; 48 | 49 | 50 | std::cout << "*s3.p = 2017" << '\n'; 51 | *s3.p = 2017; 52 | 53 | std::cout << "s1.p: " << s1.p << "; *s1.p: " << *s1.p << '\n'; 54 | std::cout << "s3.p: " << s3.p << "; *s3.p: " << *s3.p << '\n'; 55 | 56 | std::cout << '\n'; 57 | 58 | std::cout << "delete s1.p" << '\n'; 59 | delete s1.p; 60 | 61 | std::cout << "s2.p: " << s2.p << "; *s2.p: " << *s2.p << '\n'; 62 | std::cout << "s3.p: " << s3.p << "; *s3.p: " << *s3.p << '\n'; 63 | 64 | std::cout << '\n'; 65 | 66 | } 67 | -------------------------------------------------------------------------------- /source/streamState.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | 6 | std::cout << std::boolalpha << '\n'; 7 | 8 | std::cout << "In failbit-state: " << std::cin.fail() << '\n'; 9 | 10 | std::cout << '\n'; 11 | 12 | int myInt; 13 | while (std::cin >> myInt){ 14 | std::cout << "Output: " << myInt << '\n'; 15 | std::cout << "In failbit-state: " << std::cin.fail() << '\n'; 16 | std::cout << '\n'; 17 | } 18 | 19 | std::cout << "In failbit-state: " << std::cin.fail() << '\n'; 20 | std::cin.clear(); 21 | std::cout << "In failbit-state: " << std::cin.fail() << '\n'; 22 | 23 | std::cout << '\n'; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /source/stringBoundsCheck.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() { 6 | 7 | std::cout << '\n'; 8 | 9 | std::string str("1123456789"); 10 | 11 | str.at(0) = '0'; 12 | 13 | std::cout << str << '\n'; 14 | 15 | std::cout << "str.size(): " << str.size() << '\n'; 16 | std::cout << "str.capacity() = " << str.capacity() << '\n'; 17 | 18 | try { 19 | str.at(12) = 'X'; 20 | } 21 | catch (const std::out_of_range& exc) { 22 | std::cout << exc.what() << '\n'; 23 | } 24 | 25 | std::cout << '\n'; 26 | 27 | } 28 | -------------------------------------------------------------------------------- /source/stringC.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main( void ) { 5 | 6 | char text[10]; 7 | 8 | strcpy(text, "The Text is too long for text."); // too long 9 | printf("strlen(text): %u\n", strlen(text)); // missing '\0' 10 | printf("%s\n", text); 11 | 12 | text[sizeof(text)-1] = '\0'; 13 | printf("strlen(text): %u\n", strlen(text)); 14 | 15 | return 0; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /source/stringCpp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | 6 | std::string text{"The Text is not too long."}; 7 | 8 | std::cout << "text.size(): " << text.size() << '\n'; 9 | std::cout << text << '\n'; 10 | 11 | text +=" And can still grow!"; 12 | 13 | std::cout << "text.size(): " << text.size() << '\n'; 14 | std::cout << text << '\n'; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /source/stringLiteral.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() { 6 | 7 | std::string hello = "hello"; 8 | auto firstPair = std::make_pair(hello, 5); 9 | 10 | auto secondPair = std::make_pair("hello", 15); 11 | 12 | using namespace std::string_literals; 13 | // auto secondPair = std::make_pair("hello"s, 15); 14 | 15 | if (firstPair < secondPair) std::cout << "true\n"; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /source/stringView.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | void* operator new(std::size_t count) { 8 | std::cout << " " << count << " bytes" << '\n'; 9 | return malloc(count); 10 | } 11 | 12 | void getString(const std::string& str) {} 13 | 14 | void getStringView(std::string_view strView) {} 15 | 16 | int main() { 17 | 18 | std::cout << '\n'; 19 | 20 | std::cout << "std::string" << '\n'; 21 | 22 | std::string large = "0123456789-123456789-123456789-123456789"; 23 | std::string substr = large.substr(10); 24 | 25 | std::cout << '\n'; 26 | 27 | std::cout << "std::string_view" << '\n'; 28 | 29 | std::string_view largeStringView{large.c_str(), large.size()}; 30 | largeStringView.remove_prefix(10); 31 | 32 | assert(substr == largeStringView); 33 | 34 | std::cout << '\n'; 35 | 36 | std::cout << "getString" << '\n'; 37 | 38 | getString(large); 39 | getString("0123456789-123456789-123456789-123456789"); 40 | const char message []= "0123456789-123456789-123456789-123456789"; 41 | getString(message); 42 | 43 | std::cout << '\n'; 44 | 45 | std::cout << "getStringView" << '\n'; 46 | 47 | getStringView(large); 48 | getStringView("0123456789-123456789-123456789-123456789"); 49 | getStringView(message); 50 | 51 | std::cout << '\n'; 52 | 53 | } 54 | -------------------------------------------------------------------------------- /source/structuredBinding.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main() { 7 | 8 | std::cout << '\n'; 9 | 10 | std::set mySet; 11 | 12 | std::set::iterator iter; 13 | bool inserted{}; 14 | // unpacks the return value of insert into iter and inserted 15 | std::tie(iter, inserted) = mySet.insert(2011); 16 | if (inserted) std::cout << "2011 was inserted successfully\n"; 17 | 18 | // unpacks the return value of insert into iter2 and inserted2 19 | auto [iter2, inserted2] = mySet.insert(2017); 20 | if (inserted2) std::cout << "2017 was inserted successfully\n"; 21 | 22 | std::cout << '\n'; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /source/sumUp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() { 6 | 7 | std::vector vec{1, 2, 3, 4, 5, 6 ,7, 8, 9, 10}; 8 | 9 | // bad 10 | int sum1 = 0; 11 | auto sizeVec = vec.size(); 12 | for (int i = 0; i < sizeVec; ++i) sum1 += vec[i]; 13 | 14 | std::cout << sum1 << '\n'; // 55 15 | 16 | // better 17 | int sum2 = 0; 18 | for (auto v: vec) sum2 += v; 19 | std::cout << sum2 << '\n'; // 55 20 | 21 | // the best 22 | auto sum3 = std::accumulate(vec.begin(), vec.end(), 0); 23 | std::cout << sum3 << '\n'; // 55 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /source/sumUpFunctionObject.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | class SumMe { 6 | int sum{0}; 7 | public: 8 | SumMe() = default; 9 | 10 | void operator()(int x) { 11 | sum += x; 12 | } 13 | 14 | int getSum() const { 15 | return sum; 16 | } 17 | }; 18 | 19 | int main() { 20 | 21 | std::vector intVec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 22 | 23 | SumMe sumMe = std::for_each(intVec.begin(), intVec.end(), SumMe()); 24 | 25 | std::cout << '\n'; 26 | std::cout << "Sum of intVec= " << sumMe.getSum() << '\n'; 27 | std::cout << '\n'; 28 | 29 | } 30 | -------------------------------------------------------------------------------- /source/sumUpLambda.cpp: -------------------------------------------------------------------------------- 1 | // sumUpLambda.cpp 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | int main(){ 8 | 9 | std::cout << '\n'; 10 | 11 | std::vector intVec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 12 | 13 | std::for_each( 14 | intVec.begin(), intVec.end(), 15 | [sum = 0](int i) mutable { 16 | sum += i; 17 | std::cout << sum << " "; 18 | } 19 | ); 20 | 21 | std::cout << "\n\n"; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /source/swap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | template 6 | void swap(T& a, T& b) noexcept { 7 | T tmp(std::move(a)); 8 | a = std::move(b); 9 | b = std::move(tmp); 10 | } 11 | 12 | class BigArray { 13 | 14 | public: 15 | explicit BigArray(std::size_t sz): size(sz), data(new int[size]) {} 16 | 17 | BigArray(const BigArray& other): size(other.size), data(new int[other.size]) { 18 | std::cout << "Copy constructor" << '\n'; 19 | std::copy(other.data, other.data + size, data); 20 | } 21 | 22 | BigArray& operator = (const BigArray& other) { 23 | std::cout << "Copy assignment" << '\n'; 24 | if (this != &other){ 25 | delete [] data; 26 | data = nullptr; 27 | size = other.size; 28 | data = new int[size]; 29 | std::copy(other.data, other.data + size, data); 30 | } 31 | return *this; 32 | } 33 | 34 | ~BigArray() { 35 | delete[] data; 36 | } 37 | private: 38 | std::size_t size; 39 | int* data; 40 | }; 41 | 42 | int main(){ 43 | 44 | std::cout << '\n'; 45 | 46 | BigArray bigArr1(2011); 47 | BigArray bigArr2(2017); 48 | swap(bigArr1, bigArr2); 49 | 50 | std::cout << '\n'; 51 | 52 | } 53 | 54 | -------------------------------------------------------------------------------- /source/switch.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | enum class Message{ 4 | information, 5 | warning, 6 | error, 7 | fatal 8 | }; 9 | 10 | void writeMessage() { std::cerr << "message" << '\n'; } 11 | void writeWarning() { std::cerr << "warning" << '\n'; } 12 | void writeUnexpected() { std::cerr << "unexpected" << '\n'; } 13 | 14 | void withDefault(Message message) { 15 | switch(message) { 16 | case Message::information: 17 | writeMessage(); 18 | break; 19 | case Message:: warning: 20 | writeWarning(); 21 | break; 22 | default: 23 | writeUnexpected(); 24 | break; 25 | } 26 | } 27 | 28 | void withoutDefaultGood(Message message) { 29 | switch(message) { 30 | case Message::information: 31 | writeMessage(); 32 | break; 33 | case Message:: warning: 34 | writeWarning(); 35 | break; 36 | default: 37 | // nothing can be done 38 | break; 39 | } 40 | } 41 | 42 | void withoutDefaultBad(Message message) { 43 | switch(message) { 44 | case Message::information: 45 | writeMessage(); 46 | break; 47 | case Message::warning: 48 | writeWarning(); 49 | break; 50 | } 51 | } 52 | 53 | int main() { 54 | 55 | withDefault(Message::fatal); 56 | withoutDefaultGood(Message::information); 57 | withoutDefaultBad(Message::warning); 58 | 59 | } 60 | -------------------------------------------------------------------------------- /source/syncWithStdioPerformanceEndl.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | constexpr int iterations = 500; 9 | 10 | std::ifstream openFile(const std::string& myFile){ 11 | 12 | std::ifstream file(myFile, std::ios::in); 13 | if ( !file ){ 14 | std::cerr << "Can't open file "+ myFile + "!" << std::endl; 15 | exit(EXIT_FAILURE); 16 | } 17 | return file; 18 | 19 | } 20 | 21 | std::string readFile(std::ifstream file){ 22 | 23 | std::stringstream buffer; 24 | buffer << file.rdbuf(); 25 | 26 | return buffer.str(); 27 | 28 | } 29 | 30 | template 31 | auto writeToConsole(const std::string& fileContent, End end){ 32 | 33 | auto start = std::chrono::steady_clock::now(); 34 | for (auto c: fileContent) std::cout << c << end; 35 | std::chrono::duration dur = std::chrono::steady_clock::now() - start; 36 | return dur; 37 | } 38 | 39 | template 40 | auto measureTime(std::size_t iter, Function&& f){ 41 | std::chrono::duration dur{}; 42 | for (int i = 0; i < iter; ++i){ 43 | dur += f(); 44 | } 45 | return dur / iter; 46 | } 47 | 48 | int main(int argc, char* argv[]){ 49 | 50 | std::cout << std::endl; 51 | 52 | // get the filename 53 | std::string myFile; 54 | if ( argc == 2 ){ 55 | myFile= argv[1]; 56 | } 57 | else{ 58 | std::cerr << "Filename missing !" << std::endl; 59 | exit(EXIT_FAILURE); 60 | } 61 | 62 | std::ifstream file = openFile(myFile); 63 | 64 | std::string fileContent = readFile(std::move(file)); 65 | 66 | auto averageWithFlush = measureTime(iterations, [&fileContent] { // (3) 67 | return writeToConsole(fileContent, std::endl>); 68 | }); 69 | auto averageWithoutFlush = measureTime(iterations, [&fileContent] { // (4) 70 | return writeToConsole(fileContent, '\n'); 71 | }); 72 | 73 | std::cout << std::endl; 74 | std::cout << "With flush(std::endl) " << averageWithFlush.count() 75 | << " seconds" << std::endl; 76 | std::cout << "Without flush(\\n): " << averageWithoutFlush.count() 77 | << " seconds" << std::endl; 78 | std::cout << "With Flush/Without Flush: " 79 | << averageWithFlush/averageWithoutFlush << std::endl; 80 | 81 | std::cout << std::endl; 82 | 83 | } 84 | -------------------------------------------------------------------------------- /source/templateArgumentDeduction.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | template 4 | void showMe(const T& t) { 5 | std::cout << t << '\n'; 6 | } 7 | 8 | template 9 | struct ShowMe{ 10 | ShowMe(const T& t) { 11 | std::cout << t << '\n'; 12 | } 13 | }; 14 | 15 | int main() { 16 | 17 | std::cout << '\n'; 18 | 19 | showMe(5.5); // not showMe(5.5); 20 | showMe(5); // not showMe(5); 21 | 22 | ShowMe a(5.5); // not ShowMe(5.5); 23 | ShowMe b(5); // not ShowMe(5); 24 | 25 | std::cout << '\n'; 26 | 27 | } 28 | 29 | -------------------------------------------------------------------------------- /source/threadCreationPerformance.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | constexpr long long numThreads= 1'000'000; 6 | 7 | int main() { 8 | 9 | auto start = std::chrono::system_clock::now(); 10 | 11 | for (long long i = 0; i < numThreads; ++i) std::thread([]{}).detach(); 12 | 13 | std::chrono::duration dur= std::chrono::system_clock::now() - start; 14 | std::cout << "time: " << dur.count() << " seconds" << '\n'; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /source/threadDetach.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void func() { 6 | std::string s{"C++11"}; 7 | std::thread t([&s]{ std::cout << s << '\n';}); 8 | t.detach(); 9 | } 10 | 11 | int main() { 12 | func(); 13 | } 14 | -------------------------------------------------------------------------------- /source/threadSharesOwnership.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std::literals::chrono_literals; 5 | 6 | struct MyInt { 7 | int val{2017}; 8 | ~MyInt() { 9 | std::cout << "Goodbye" << '\n'; 10 | } 11 | }; 12 | 13 | void showNumber(const MyInt* myInt) { 14 | std::cout << myInt->val << '\n'; 15 | } 16 | 17 | void threadCreator() { 18 | MyInt* tmpInt= new MyInt; 19 | 20 | std::thread t1(showNumber, tmpInt); 21 | std::thread t2(showNumber, tmpInt); 22 | 23 | t1.detach(); 24 | t2.detach(); 25 | } 26 | 27 | int main() { 28 | 29 | std::cout << '\n'; 30 | 31 | threadCreator(); 32 | std::this_thread::sleep_for(1s); 33 | 34 | std::cout << '\n'; 35 | 36 | } 37 | -------------------------------------------------------------------------------- /source/threadSharesOwnershipSharedPtr.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std::literals::chrono_literals; 6 | 7 | struct MyInt { 8 | int val{2017}; 9 | ~MyInt() { 10 | std::cout << "Goodbye" << '\n'; 11 | } 12 | }; 13 | 14 | void showNumber(std::shared_ptr myInt) { 15 | std::cout << myInt->val << '\n'; 16 | } 17 | 18 | void threadCreator() { 19 | auto sharedPtr = std::make_shared(); 20 | 21 | std::thread t1(showNumber, sharedPtr); 22 | std::thread t2(showNumber, sharedPtr); 23 | 24 | t1.detach(); 25 | t2.detach(); 26 | } 27 | 28 | int main() { 29 | 30 | std::cout << '\n'; 31 | 32 | threadCreator(); 33 | std::this_thread::sleep_for(1s); 34 | 35 | std::cout << '\n'; 36 | 37 | } 38 | -------------------------------------------------------------------------------- /source/threadWithJoin.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | 6 | std::jthread t([]{ 7 | std::cout << std::this_thread::get_id() << '\n'; 8 | }); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /source/threadWithoutJoin.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | 6 | std::thread t([]{ 7 | std::cout << std::this_thread::get_id() << '\n'; 8 | }); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /source/transformExclusiveScan.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main() { 7 | 8 | std::cout << '\n'; 9 | 10 | std::vector resVec{1, 2, 3, 4, 5, 6, 7, 8, 9}; 11 | std::vector resVec1(resVec.size()); 12 | std::transform_exclusive_scan(std::execution::par, 13 | resVec.begin(), resVec.end(), 14 | resVec1.begin(), 0, 15 | [](int fir, int sec){ return fir + sec; }, 16 | [](int arg){ return arg * arg; }); 17 | 18 | std::cout << "transform_exclusive_scan: "; 19 | for (auto v: resVec1) std::cout << v << " "; 20 | 21 | std::cout << '\n'; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /source/typeEnum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | enum class Color1 { 4 | red, 5 | blue, 6 | green 7 | }; 8 | 9 | enum struct Color2: char { 10 | red, 11 | blue, 12 | green 13 | }; 14 | 15 | int main() { 16 | 17 | std::cout << sizeof(Color1) << '\n'; 18 | std::cout << sizeof(Color2) << '\n'; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /source/uniformInitialization.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // Initialisation of a C-Array 6 | class Array { 7 | public: 8 | Array(): myData{1,2,3,4,5} {} 9 | private: 10 | const int myData[5]; 11 | }; 12 | 13 | class MyClass { 14 | public: 15 | int x; 16 | double y; 17 | }; 18 | 19 | class MyClass2 { 20 | public: 21 | MyClass2(int fir, double sec): x{fir}, y{sec} {} 22 | private: 23 | int x; 24 | double y; 25 | }; 26 | 27 | int main() { 28 | 29 | // Direct initialization of standard containers 30 | int intArray[]= {1, 2, 3, 4, 5}; 31 | std::vector intArray1{1, 2, 3, 4, 5}; 32 | std::map myMap{ {"Scott", 1976}, {"Dijkstra", 1972} }; 33 | 34 | Array arr; 35 | 36 | // Defaut initialization of arbitrary objects 37 | int i{}; // i becomes 0 38 | std::string s{}; // s becomes "" 39 | std::vector v{}; // v becomes an empty vector 40 | double d{}; // d becomes 0.0 41 | 42 | // Direct initialization of an arbitrary object with public members 43 | MyClass myClass{2011, 3.14}; 44 | MyClass myClass1= {2011, 3.14}; 45 | 46 | // Initialization of an arbitrary object using the constructor 47 | MyClass2 myClass2{2011, 3.14}; 48 | MyClass2 myClass3= {2011, 3.14}; 49 | 50 | } 51 | -------------------------------------------------------------------------------- /source/uniqPtrMove.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Widget { 5 | explicit Widget(int) {} 6 | }; 7 | 8 | void sink(std::unique_ptr uniqPtr) { 9 | // do something with uniqPtr, then dispose of it 10 | 11 | } 12 | 13 | int main() { 14 | 15 | auto uniqPtr = std::make_unique(1998); 16 | 17 | sink(std::move(uniqPtr)); // OK 18 | sink(uniqPtr); // ERROR 19 | 20 | } 21 | -------------------------------------------------------------------------------- /source/uniqPtrReference.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Widget{ 5 | Widget(int) {} 6 | }; 7 | 8 | void reseat(std::unique_ptr& uniqPtr) { 9 | uniqPtr.reset(new Widget(2003)); 10 | // do something with uniqPtr 11 | } 12 | 13 | int main() { 14 | 15 | auto uniqPtr = std::make_unique(1998); 16 | 17 | reseat(std::move(uniqPtr)); // ERROR 18 | reseat(uniqPtr); // OK 19 | 20 | } 21 | -------------------------------------------------------------------------------- /source/unspecified.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void func(int fir, int sec) { 4 | std::cout << "(" << fir << "," << sec << ")" << '\n'; 5 | } 6 | 7 | int main(){ 8 | int i = 0; 9 | func(i++, i++); 10 | } 11 | -------------------------------------------------------------------------------- /source/vararg.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int sum(int num, ... ) { 5 | 6 | int sum = 0; 7 | 8 | va_list argPointer; 9 | va_start(argPointer, num ); 10 | for( int i = 0; i < num; i++ ) 11 | sum += va_arg(argPointer, int ); 12 | va_end(argPointer); 13 | 14 | return sum; 15 | } 16 | 17 | int main() { 18 | 19 | std::cout << "sum(1, 5): " << sum(1, 5) << '\n'; 20 | std::cout << "sum(3, 1, 2, 3): " << sum(3, 1, 2, 3) << '\n'; 21 | std::cout << "sum(3, 1, 2, 3, 4): " << sum(3, 1, 2, 3, 4) << '\n'; 22 | std::cout << "sum(3, 1, 2, 3.5): " << sum(3, 1, 2, 3.5) << '\n'; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /source/variant.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | 6 | std::variant v, w; 7 | int i = std::get(v); // i is 0 8 | 9 | v = 12; // v contains int 10 | int j = std::get(v); 11 | 12 | w = std::get(v); 13 | w = std::get<0>(v); // same effect as the previous line 14 | w = v; // same effect as the previous line 15 | 16 | 17 | // std::get(v); // error: no double in [int, float] 18 | // std::get<3>(v); // error: valid index values are 0 and 1 19 | 20 | try{ 21 | std::get(w); // w contains int, not float: will throw 22 | } 23 | catch (std::bad_variant_access&) {} 24 | 25 | v = 5.5f; // switch to float 26 | v = 5; // and back 27 | 28 | std::variant v2("abc"); // converting constructors work when unambiguous 29 | v2 = "def"; // converting assignment also works when unambiguous 30 | 31 | } 32 | -------------------------------------------------------------------------------- /source/vectorMemory.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | template 6 | void showInfo(const T& t, const std::string& name) { 7 | 8 | std::cout << name << " t.size(): " << t.size() << '\n'; 9 | std::cout << name << " t.capacity(): " << t.capacity() << '\n'; 10 | 11 | } 12 | 13 | int main() { 14 | 15 | std::cout << '\n'; 16 | 17 | std::vector vec; 18 | 19 | std::cout << "Maximal size: " << '\n'; 20 | std::cout << "vec.max_size(): " << vec.max_size() << '\n'; 21 | std::cout << '\n'; 22 | 23 | std::cout << "Empty vector: " << '\n'; 24 | showInfo(vec, "Vector"); 25 | std::cout << '\n'; 26 | 27 | std::cout << "Initialized with five values: " << '\n'; 28 | vec = {1,2,3,4,5}; 29 | showInfo(vec, "Vector"); 30 | std::cout << '\n'; 31 | 32 | std::cout << "Added four additional values: " << '\n'; 33 | vec.insert(vec.end(),{6,7,8,9}); 34 | showInfo(vec,"Vector"); 35 | std::cout << '\n'; 36 | 37 | std::cout << "Resized to 30 values: " << '\n'; 38 | vec.resize(30); 39 | showInfo(vec,"Vector"); 40 | std::cout << '\n'; 41 | 42 | std::cout << "Reserved space for at least 1000 values: " << '\n'; 43 | vec.reserve(1000); 44 | showInfo(vec,"Vector"); 45 | std::cout << '\n'; 46 | 47 | std::cout << "Shrinked to the current size: " << '\n'; 48 | vec.shrink_to_fit(); 49 | showInfo(vec,"Vector"); 50 | 51 | } 52 | -------------------------------------------------------------------------------- /source/virtualCall.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct Base { 4 | Base() { 5 | f(); 6 | } 7 | virtual void f() { 8 | std::cout << "Base called" << '\n'; 9 | } 10 | }; 11 | 12 | struct Derived: Base { 13 | void f() override { 14 | std::cout << "Derived called" << '\n'; 15 | } 16 | }; 17 | 18 | int main() { 19 | 20 | std::cout << '\n'; 21 | 22 | Derived d; 23 | 24 | std::cout << '\n'; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /source/virtualMemberFunctions.cpp: -------------------------------------------------------------------------------- 1 | class Shape { 2 | template 3 | virtual void intersect(T* p) {}; 4 | }; 5 | 6 | int main(){ 7 | 8 | Shape shape; 9 | 10 | } 11 | --------------------------------------------------------------------------------