{"id":15047148,"url":"https://github.com/izzypt/cpp-module-06","last_synced_at":"2026-02-03T19:32:28.839Z","repository":{"id":211158362,"uuid":"728363209","full_name":"izzypt/CPP-Module-06","owner":"izzypt","description":"This module is designed to help you understand the different casts in CPP. ","archived":false,"fork":false,"pushed_at":"2023-12-10T21:47:55.000Z","size":61,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-13T19:47:38.366Z","etag":null,"topics":["cast","cpp98"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/izzypt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-12-06T19:28:47.000Z","updated_at":"2023-12-11T17:05:38.000Z","dependencies_parsed_at":"2023-12-15T09:30:52.300Z","dependency_job_id":null,"html_url":"https://github.com/izzypt/CPP-Module-06","commit_stats":null,"previous_names":["izzypt/cpp-module-06"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/izzypt/CPP-Module-06","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/izzypt%2FCPP-Module-06","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/izzypt%2FCPP-Module-06/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/izzypt%2FCPP-Module-06/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/izzypt%2FCPP-Module-06/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/izzypt","download_url":"https://codeload.github.com/izzypt/CPP-Module-06/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/izzypt%2FCPP-Module-06/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262151872,"owners_count":23266935,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cast","cpp98"],"created_at":"2024-09-24T20:54:50.835Z","updated_at":"2026-02-03T19:32:28.832Z","avatar_url":"https://github.com/izzypt.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CPP-Module-06\n This module is designed to help you understand the different casts in CPP. \n\n\n # Table of Content\n\n - [Type Conversion](#conversion)\n - [Differences and profile of each Cast](#differences)\n - [std::numeric_limits](#limits)\n - [Static member functions and variables](#static)\n - [What is Serialization and DeSerialization](#serialization)\n\n\u003ca id=\"conversion\"\u003e\u003c/a\u003e\n# Type Conversion\n\nIn C++, type conversion refers to \u003cins\u003ethe process of converting a value from one data type to another\u003c/ins\u003e. \n\nThere are several types of type conversions in C++:\n\n### 1. Implicit Conversion (Automatic Type Conversion):\n\n```cpp\n\nint intValue = 5;\nfloat floatValue = intValue; // Implicit conversion from int to float\n```\n\n### 2. Explicit Conversion (Type Casting):\n\n2.1 - C-Style Casting:\n\n```cpp\n\ndouble doubleValue = 3.14;\nint intValue = (int)doubleValue; // C-style casting\n```\n\n2.2 - Functional Casting:\n\n```cpp\n\ndouble doubleValue = 3.14;\nint intValue = int(doubleValue); // Functional casting\n```\n\n### 3. Static Cast:\nThe static_cast operator takes an expression as input, and returns the evaluated value converted to the type specified inside the angled brackets. \n\nstatic_cast is best used to convert one fundamental type into another.\n\n```cpp\n\ndouble doubleValue = 3.14;\nint intValue = static_cast\u003cint\u003e(doubleValue); // Static cast\n```\n\nThe main advantage of static_cast is that it provides compile-time type checking, making it harder to make an inadvertent error.\n\nstatic_cast is also (intentionally) less powerful than C-style casts, so you can’t inadvertently remove const or do other things you may not have intended to do.\n\n### 4. Dynamic Cast:\n\nAlthough dynamic casts have a few different capabilities, by far the most common use for dynamic casting is for converting base-class pointers into derived-class pointers. \n\nThis process is called downcasting\n\n```cpp\n\nclass Base {\n  // ...\n};\n\nclass Derived : public Base {\n  // ...\n};\n\nBase* basePtr = new Derived();\nDerived* derivedPtr = dynamic_cast\u003cDerived*\u003e(basePtr); // Dynamic cast\n```\n\n### 5. Reinterpret Cast:\n\n  Converts a pointer type to another pointer type, even if they are not related.\n  \n  Often used for low-level casting, such as casting between pointers and integers.\n  \n  Considered unsafe and should be used with caution.\n\n```cpp\n\nint intValue = 42;\ndouble* doublePtr = reinterpret_cast\u003cdouble*\u003e(\u0026intValue); // Reinterpret cast\n```\n\n\u003ca id=\"differences\"\u003e\u003c/a\u003e\n# Differences and profile of each cast\n\n### Static Cast:\n\n  - Used for conversions between related types.\n  - Resolved at compile-time.\n  - Generally performs simple conversions, such as widening or narrowing of numeric types.\n  - Safer than C-style casting but doesn't provide runtime type checking.\n\n```cpp\n\ndouble doubleValue = 3.14;\nint intValue = static_cast\u003cint\u003e(doubleValue); // Static cast\n```\n\n### Dynamic Cast:\n\n  - Primarily used in polymorphic class hierarchies (classes with at least one virtual function).\n  - Performs a runtime check to ensure the conversion is valid.\n  - Returns a null pointer if the conversion is not possible (when dealing with pointers), or throws a std::bad_cast exception (when dealing with references).\n  - Provides a safer way to downcast within inheritance hierarchies.\n\n```cpp\n\nclass Base {\n  // ...\n};\n\nclass Derived : public Base {\n  // ...\n};\n\nBase* basePtr = new Derived();\nDerived* derivedPtr = dynamic_cast\u003cDerived*\u003e(basePtr); // Dynamic cast\n```\n\n### Const Cast:\n\n - Used to add or remove the const qualifier from a variable.\n - Allows modifying a variable that was originally declared as const.\n - Should be used with caution to avoid undefined behavior.\n\n```cpp\n\nconst int constValue = 42;\nint nonConstValue = const_cast\u003cint\u003e(constValue); // Remove const qualifier\n```\n\n### Reinterpret Cast:\n\n - Converts a pointer type to another pointer type, even if they are not related.\n - Often used for low-level casting, such as casting between pointers and integers.\n - Considered unsafe and should be used with caution.\n\n```cpp\n\n    int intValue = 42;\n    double* doublePtr = reinterpret_cast\u003cdouble*\u003e(\u0026intValue); // Reinterpret cast\n```\n\nIn summary, each type of cast serves a specific purpose:\n\n - Static cast is a general-purpose cast for related types, performed at compile-time.\n - Dynamic cast is used for safe downcasting in polymorphic class hierarchies, with runtime type checking.\n - Const cast is used to add or remove the const qualifier.\n - Reinterpret cast is a low-level cast that is less safe and should be used carefully.\n\n\u003ca id=\"limits\"\u003e\u003c/a\u003e\n# std::numeric_limits\n\n`std::numeric_limits` is a template class in the C++ Standard Library that provides information about the properties of numeric types. \n\nIt is defined in the `\u003climits\u003e` header and is part of the `\u003climits\u003e` header template library.\n\n\u003e The primary purpose of `std::numeric_limits` is to provide a standardized way to obtain information about the characteristics of numeric types, such as the minimum and maximum representable values, whether the type is signed or unsigned, and other properties.\n\nHere are some common members of `std::numeric_limits`:\n\n- **`min()` and `max()`**: These functions return the minimum and maximum finite representable values of a numeric type.\n\n- **`lowest()`**: This function returns the most negative finite representable value for a floating-point type.\n\n- **`is_integer`**: A boolean value indicating whether the type is an integer type (`true` for integer types, `false` for floating-point types).\n\n- **`is_signed`**: A boolean value indicating whether the type is signed (`true` for signed types, `false` for unsigned types).\n\n- **`digits` and `digits10`**: These members indicate the number of binary digits (bits) and decimal digits that can be represented exactly in the given numeric type.\n\n- **`epsilon()`**: Returns the difference between 1 and the smallest value greater than 1 that is representable for the given floating-point type.\n\n- **`infinity()` and `quiet_NaN()`**: Return positive infinity and a quiet NaN (Not a Number) for floating-point types.\n\nHere's a simple example demonstrating the use of `std::numeric_limits`:\n\n```cpp\n#include \u003ciostream\u003e\n#include \u003climits\u003e\n\nint main() {\n    std::cout \u003c\u003c \"Minimum value for int: \" \u003c\u003c std::numeric_limits\u003cint\u003e::min() \u003c\u003c std::endl;\n    std::cout \u003c\u003c \"Maximum value for int: \" \u003c\u003c std::numeric_limits\u003cint\u003e::max() \u003c\u003c std::endl;\n    std::cout \u003c\u003c \"Is int signed? \" \u003c\u003c std::numeric_limits\u003cint\u003e::is_signed \u003c\u003c std::endl;\n\n    std::cout \u003c\u003c \"Minimum value for float: \" \u003c\u003c std::numeric_limits\u003cfloat\u003e::min() \u003c\u003c std::endl;\n    std::cout \u003c\u003c \"Maximum value for float: \" \u003c\u003c std::numeric_limits\u003cfloat\u003e::max() \u003c\u003c std::endl;\n\n    return 0;\n}\n```\n\nThis program prints information about the minimum and maximum values and signedness of `int` and `float` types using `std::numeric_limits`.\n\n\u003ca id=\"static\"\u003e\u003c/a\u003e\n# Static member functions\n\nStatic member functions in C++ are class-level functions that are associated with the class itself rather than with individual instances (objects) of the class. \n\nThey are declared using the static keyword, and we can call such a function with a class name without the need to create an object.\n\nStatic member functions are commonly used for operations that are related to the class as a whole rather than to specific instances.\n\nSyntax: \n\nThe syntax for defining a static member function in C++ is as follows:\n```cpp\n    class ClassName\n    {\n        public:\n            static returnType functionName(parameters)\n            {\n                 // Function body implementation\n            }\n    };\n```\n\n# Static member variables\n\n![image](https://github.com/izzypt/CPP-Module-06/assets/73948790/a45fa92f-c0b3-4874-8d9b-87d6ed2d2530)\n\n\nBefore we go into the static keyword as applied to member variables, first consider the following class:\n\n```cpp\n\n#include \u003ciostream\u003e\n\nstruct Something\n{\n    int value{ 1 };\n};\n\nint main()\n{\n    Something first{};\n    Something second{};\n\n    first.value = 2;\n\n    std::cout \u003c\u003c first.value \u003c\u003c '\\n';\n    std::cout \u003c\u003c second.value \u003c\u003c '\\n';\n\n    return 0;\n}\n```\n\n- When we instantiate a class object, each object gets its own copy of all normal member variables. \n\n- In this case, because we have declared two Something class objects, we end up with two copies of value: first.value, and second.value. first.value is distinct from second.value. Consequently, the program above prints:\n\n```\n2\n1\n```\n\nMember variables of a class can be made static by using the static keyword. \n\nUnlike normal member variables, static member variables are shared by all objects of the class. Consider the following program, similar to the above:\n\n```cpp\n#include \u003ciostream\u003e\n\nstruct Something\n{\n    static int s_value; // now static\n};\n\nint Something::s_value{ 1 }; // initialize s_value to 1\n\nint main()\n{\n    Something first{};\n    Something second{};\n\n    first.s_value = 2;\n\n    std::cout \u003c\u003c first.s_value \u003c\u003c '\\n';\n    std::cout \u003c\u003c second.s_value \u003c\u003c '\\n';\n    return 0;\n}\n```\nThis program produces the following output:\n```cpp\n2\n2\n```\nBecause s_value is a static member variable, s_value is shared between all objects of the class. \n\nConsequently, first.s_value is the same variable as second.s_value. The above program shows that the value we set using first can be accessed using second!\n\n\u003ca id=\"serialization\"\u003e\u003c/a\u003e\n# What is serialization and deserialization\n\nSerialization is a technique for converting an item into a byte sequence that may be kept in memory. Once produced, the byte stream can be streamed to a remote receiving end through a communication channel. Deserialization is the inverse of serialization.\n\nOnce produced, the deserliazation process byte stream converts into the original object definition. The C++ runtimes used this method to transfer compiled memory structures through the different components of application dynamic runtimes.\n\n###\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fizzypt%2Fcpp-module-06","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fizzypt%2Fcpp-module-06","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fizzypt%2Fcpp-module-06/lists"}