Initial commit

This commit is contained in:
2025-02-08 20:21:42 -05:00
commit a4f7e614f1
7 changed files with 127 additions and 0 deletions

18
CMakeLists.txt Normal file
View File

@@ -0,0 +1,18 @@
cmake_minimum_required(VERSION 3.18)
project(polymorphism)
if (PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
message(FATAL_ERROR "In-Source builds are not allowed")
endif()
set(CMAKE_CXX_STANDARD 20)
file(GLOB_RECURSE HEADERS "include/*.h")
file(GLOB_RECURSE SOURCES "src/*.cpp" "main.cpp")
include_directories("include")
add_executable(polymorphism ${SOURCES})
set_target_properties(polymorphism PROPERTIES LINKER_LANGUAGE CXX)

24
LICENSE Normal file
View File

@@ -0,0 +1,24 @@
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <https://unlicense.org>

View File

@@ -0,0 +1,21 @@
#pragma once
class BaseClass {
protected:
bool b;
float f1;
float f2;
public:
virtual void printClassName(); //For a class to be "polymorphic", You *must* have at-least one virtual member.
virtual ~BaseClass() = default; //If you don't have any reason to have virtual functions, you can make a virtual destructor.
}; //Virtual has a ton of uses. The *huge* one is the ability to use dynamic cast. -> someFunc.cpp
class DerivedClass1 : public BaseClass {
public:
void printClassName() override; //Using "Virtual Functions" we "Override" the function inside the base class. -> polymorphicClass.cpp
};
class DerivedClass2 : public BaseClass {
public:
void printClassName() override;
};

4
include/someFunc.h Normal file
View File

@@ -0,0 +1,4 @@
#pragma once
#include <polymorphicClass.h>
void someFunc(BaseClass* bC);

29
main.cpp Normal file
View File

@@ -0,0 +1,29 @@
#include <someFunc.h>
auto* b = new BaseClass; //Allocate an instance of each class from the heap,
auto* dc1 = new DerivedClass1; //Doing this is *really* slow compared to the stack.
auto* dc2 = new DerivedClass2; //But it's fantastic for things you'll allocate once and use a LOT.
int main() { //Look at polymorphicClass.h.
someFunc(b);
someFunc(dc1);
someFunc(dc2);
delete b; //Delete them when you're done so that you don't mem-leak.
delete dc1;
delete dc2;
//b->printClassName(); //Don't access them after you delete them.
//This is called a "use after free" and is very bad.
return 0;
}
#pragma region windows
#ifdef _WIN32
extern "C" {
int wmain(int argc, wchar_t* argv[]) {
return main();
}
}
#endif
#pragma endregion

13
src/polymorphicClass.cpp Normal file
View File

@@ -0,0 +1,13 @@
#include <polymorphicClass.h>
#include <iostream>
void BaseClass::printClassName() { //The function in the base class.
std::cout << "Base Class" << std::endl;
}
void DerivedClass1::printClassName() { //The overridden version of the same function.
std::cout << "Derived Class 1" << std::endl; //These create "Virtual Function Table" entries.
} //The V-Table stores pointers to which version of the function should be run for each derived class.
//You can also specifically run the version from the Base Class. In this case, BaseClass::printClassName();
void DerivedClass2::printClassName() {
std::cout << "Derived Class 2" << std::endl;
}

18
src/someFunc.cpp Normal file
View File

@@ -0,0 +1,18 @@
#include <someFunc.h>
#include <iostream>
void someFunc(BaseClass* bC) { //We can take the BaseClass as a function parameter, Which also allows us to accept any of the derived classes.
if (auto* dc1 = dynamic_cast<DerivedClass1*>(bC)) { //If we passed in DerivedClass1.
std::cout << "You passed in "; dc1->printClassName(); //The overridden version of the function from DerivedClass1 will run.
return; //Exit the void function early.
}
if (auto* dc2 = dynamic_cast<DerivedClass2*>(bC)) {
std::cout << "You passed in "; dc2->printClassName();
return;
}
if (auto* b = dynamic_cast<BaseClass*>(bC)) //If we passed in the base class and not any derived class.
//*Must* be checked for last if you'll be passing in BaseClass because this will always succeed.
std::cout << "You passed in ", b->printClassName();
}