add virtual methods

add interface
add pure virtual
add casts
add template example
This commit is contained in:
2025-02-12 16:51:05 +01:00
parent a0b1dd4c08
commit 0e140ba81f
9 changed files with 97 additions and 3 deletions
+6
View File
@@ -2,6 +2,7 @@
ClassA::ClassA() : _pNumber(new int(0)) ClassA::ClassA() : _pNumber(new int(0))
{ {
std::cout << "ClassA called" << std::endl;
} }
ClassA::ClassA(const ClassA& other) ClassA::ClassA(const ClassA& other)
@@ -15,9 +16,14 @@ ClassA::ClassA(const ClassA& other)
ClassA::~ClassA() ClassA::~ClassA()
{ {
std::cout << "~ClassA called" << std::endl;
if (_pNumber != nullptr) if (_pNumber != nullptr)
{ {
delete _pNumber; delete _pNumber;
_pNumber = nullptr; _pNumber = nullptr;
} }
} }
void ClassA::Print()
{
}
+5 -1
View File
@@ -1,6 +1,7 @@
#pragma once #pragma once
#include "IPrintable.h"
class ClassA class ClassA : public IPrintable
{ {
// private // private
@@ -10,6 +11,9 @@ public:
ClassA(const ClassA& other); // copy constructor ClassA(const ClassA& other); // copy constructor
~ClassA(); // destructor ~ClassA(); // destructor
const int& GetNumber() const { return *_pNumber; } // implicit inline method
void Print() override;
protected: protected:
// protected // protected
+12
View File
@@ -0,0 +1,12 @@
#include "ClassB.h"
ClassB::ClassB()
{
std::cout << "ClassB called" << std::endl;
GetNumber();
}
ClassB::~ClassB()
{
std::cout << "~ClassB called" << std::endl;
}
+10
View File
@@ -0,0 +1,10 @@
#pragma once
#include "ClassA.h"
class ClassB : public ClassA
{
public:
ClassB();
~ClassB();
};
+10
View File
@@ -0,0 +1,10 @@
#pragma once
#include <iostream>
class IPrintable
{
public:
IPrintable() { std::cout << "IPrintable called" << std::endl; }
virtual ~IPrintable() { std::cout << "~IPrintable called" << std::endl; }
virtual void Print() = 0; // pure virtual
};
+10
View File
@@ -10,4 +10,14 @@ void changeInt(int n);
void changeIntPointer(int* pN); void changeIntPointer(int* pN);
void changeIntReference(int& n); void changeIntReference(int& n);
template<class T>
void safeDelete(T*& pObj)
{
if (pObj != nullptr)
{
delete pObj;
pObj = nullptr;
}
}
#endif // !__FUNCTIONS_H__ #endif // !__FUNCTIONS_H__
+3
View File
@@ -128,12 +128,15 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="ClassA.cpp" /> <ClCompile Include="ClassA.cpp" />
<ClCompile Include="ClassB.cpp" />
<ClCompile Include="functions.cpp" /> <ClCompile Include="functions.cpp" />
<ClCompile Include="main.cpp" /> <ClCompile Include="main.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="ClassA.h" /> <ClInclude Include="ClassA.h" />
<ClInclude Include="ClassB.h" />
<ClInclude Include="functions.h" /> <ClInclude Include="functions.h" />
<ClInclude Include="IPrintable.h" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
+9
View File
@@ -24,6 +24,9 @@
<ClCompile Include="ClassA.cpp"> <ClCompile Include="ClassA.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="ClassB.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="functions.h"> <ClInclude Include="functions.h">
@@ -32,5 +35,11 @@
<ClInclude Include="ClassA.h"> <ClInclude Include="ClassA.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="ClassB.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="IPrintable.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>
+32 -2
View File
@@ -3,6 +3,7 @@
#include <memory> #include <memory>
#include "functions.h" #include "functions.h"
#include "ClassA.h" #include "ClassA.h"
#include "ClassB.h"
using namespace std; using namespace std;
@@ -107,8 +108,37 @@ int main()
//} //}
//cout << "sn2 refs: " << sn2.use_count() << endl; //cout << "sn2 refs: " << sn2.use_count() << endl;
ClassA classA; //ClassA classA;
ClassA classA2 = classA; //ClassA classA2 = classA;
//ClassB classB;
//int n = classA.GetNumber();
//cout << n << endl;
//classB.GetNumber();
IPrintable* pPrintable = nullptr;
pPrintable = new ClassB();
//(*pPrintable).Print();
//pPrintable->Print(); // same line as above, but simpler
////ClassB* pClassB2 = (ClassB*)pPrintable; // C-Cast, CAUTION: DANGER!!!
//ClassB* pClassB2 = dynamic_cast<ClassB*>(pPrintable); // c++ cast for polymorhpic cast
//float f = 1.0f;
//int i = static_cast<int>(f); // c++ cast, convert one static data type into another
////int* nonsense = reinterpret_cast<int*>(pPrintable); // c++ cast like C-Cast, CAUTION: DANGER!!!
//const char csz[13] = "Hello World";
//char* sz = const_cast<char*>(csz);
// What's the difference?
//const int* cip;
//int const* icp;
//int* const ipc;
//const int const* cicp;
//const int* const cipc;
//int const* const icpc;
//const int const* const cicpc;
//delete pPrintable;
//pPrintable = nullptr;
safeDelete(pPrintable);
return 0; return 0;
} }