Initial commit
This commit is contained in:
18
CMakeLists.txt
Normal file
18
CMakeLists.txt
Normal 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
24
LICENSE
Normal 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>
|
21
include/polymorphicClass.h
Normal file
21
include/polymorphicClass.h
Normal 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
4
include/someFunc.h
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <polymorphicClass.h>
|
||||||
|
|
||||||
|
void someFunc(BaseClass* bC);
|
29
main.cpp
Normal file
29
main.cpp
Normal 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
13
src/polymorphicClass.cpp
Normal 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
18
src/someFunc.cpp
Normal 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();
|
||||||
|
}
|
Reference in New Issue
Block a user