
1. 다이아몬드 상속을 받는 경우, 문제를 야기할 수 있지만, 명시적으로 캐스팅을 함으로써 문제를 해결한다.
//Library.h
#pragma once
struct IObject
{
virtual void __stdcall Addref() = 0;
virtual void __stdcall Release() = 0;
virtual void* __stdcall As(const char* type) = 0;
};
struct IHen : IObject
{
virtual void __stdcall Cluck() = 0;
virtual void __stdcall Roost() = 0;
};
struct IHen2 : IHen
{
virtual void __stdcall Forage() = 0;
};
struct IOfflineChicken : IObject
{
virtual void __stdcall Load(const char* file) = 0;
virtual void __stdcall Save(const char* file) = 0;
};
IHen* __stdcall CreateHen();
//Library.cpp
#include "Library.h"
#include <Windows.h>
#define TRACE OutputDebugStringA
struct Hen : IHen2, IOfflineChicken
{
unsigned m_count;
Hen() : m_count(0)
{
TRACE("Constructor\n");
}
~Hen()
{
TRACE("Destructor\n");
}
// IObject
void __stdcall Addref()
{
++m_count;
}
void __stdcall Release()
{
if (0 == --m_count)
{
delete this;
}
}
void* __stdcall As(const char* type)
{
if (0 == strcmp(type, "IHen2") ||
0 == strcmp(type, "IHen") ||
0 == strcmp(type, "IObject"))
{
Addref();
return static_cast<IHen2*>(this);
}
else if (0 == strcmp(type, "IOfflineChicken"))
{
Addref();
return static_cast<IOfflineChicken*>(this);
}
else
{
return 0;
}
}
// IHen
void __stdcall Cluck()
{
TRACE("Cluck\n");
}
void __stdcall Roost()
{
TRACE("Roost\n");
}
// IHen2
void __stdcall Forage()
{
TRACE("Forage\n");
}
// IOfflineChicken
void __stdcall Load(const char* /*file*/)
{
}
void __stdcall Save(const char* /*file*/)
{
}
};
IHen* __stdcall CreateHen()
{
IHen* result = new Hen;
result->Addref();
return result;
}
2. 레퍼런스 카운터도 잘 동작하지만, hen과 hen2는 같은 주소 값인 반면, As 메소드 덕에, offline은 hen과는 다른 주소 값을 갖는다.
#include "Library.h"
int main()
{
IHen* hen = CreateHen();
hen->Cluck();
hen->Roost();
IHen2* hen2 = static_cast<IHen2*>(hen->As("IHen2"));
if (hen2)
{
hen2->Forage();
hen2->Release();
}
IOfflineChicken* offline =
static_cast<IOfflineChicken*>(hen->As("IOfflineChicken"));
if (offline)
{
offline->Save("filename");
offline->Release();
}
hen->Release();
}
'삽질 > COM' 카테고리의 다른 글
COM study note 8 IUnknown 이식 (0) | 2020.10.30 |
---|---|
COM study note 7 (0) | 2020.10.29 |
COM study note 5 레퍼런스 카운터 (0) | 2020.10.28 |
COM study note 4 인터페이스 (0) | 2020.10.27 |
COM study note 3 다이나믹 링킹 (0) | 2020.10.27 |