본문으로 바로가기

 

#pragma comment(lib, "dxgi.lib")
#include <iostream>
#include <d3d12.h>
#include <dxgi.h>
#include <vector>
#include <wrl.h>
#include <string>
using namespace std;

int main() {
	UINT i{ 0 };
	IDXGIAdapter* adapter{ nullptr };
	vector<IDXGIAdapter*> adapterList;
	Microsoft::WRL::ComPtr<IDXGIFactory1> mdxgiFactory;
	CreateDXGIFactory1(IID_PPV_ARGS(&mdxgiFactory));

	while (mdxgiFactory->EnumAdapters(i, &adapter) != DXGI_ERROR_NOT_FOUND) {
		DXGI_ADAPTER_DESC desc;
		adapter->GetDesc(&desc);

		wstring text{ L"***Adapter: " };
		text += desc.Description;
		text += L"\n";

		wcout << text.c_str() << endl;
		++i;
	}
    // ... use adapterList
}

dx12 의 display adapter 부분에서, IDXGIFactory1 은 abstract class 인데 어떻게 선언이 가능해졌나? 에 대해 궁금해서 

조금 끄적이게 됨

 

#include <iostream>

using namespace std;
class test {
public:
	virtual void func() = 0;
};
int main() {
	test c;	// error, 추상클래스 형식을 사용할 수 없습니다.
}

test는 abstract class 이므로, 선언할 수 없음

 

#include <iostream>

using namespace std;
class test {
public:
	virtual void func() = 0;
};

template <typename T>
class myPointer {
public:

};
int main() {
	myPointer<test> c;	// ok
}

위는 가능함, 컴파일 단계에서도 오류를 발생시키지 않음, T를 실제로 만들어내지 않았기 때문에 

 

#include <iostream>

using namespace std;
class test {
public:
	virtual void func() = 0;
};

template <typename T>
class myPointer {
public:
	T t;
};
int main() {
	myPointer<test> c;	// error, 추상클래스 
}

하지만 T를 실제로 만들어 냈다면, 컴파일 단계에서 error가 발생함

이는 template 의 문법과 맞음 ( 실제로 사용하지 않으면 생성또한 되지 않음 )

 

ComPtr 은 Microsoft 의 smartPointer 이기때문에, 개발자가 메모리에 접근하지 않으며 안전하게 쓰고 지울 수 있게 하기 위해 위같은 접근 방식을 택한 것 같음

 

위는 순수 가상 함수이기 때문에 구현부 또한 필요하며, 실제 Instance 를 생성해줄 함수 또한 필요함 ( Factory )

 

#include <iostream>

using namespace std;
class based {
public:
	virtual void func1() = 0;
};

template <typename T>
class myPointer {
public:
	~myPointer() {
		delete t;	// 간단한 스마트 포인터처럼, 받은 포인터를 자기가 직접 삭제해줌
	}
	T* operator*() {
		return t;
	}
	T*& operator&() {
		return t;
	}
	T* t;
};

class derived : public based {
public:
	void func1() override {
		// 구현부
	}
};

void getFactory(based*& t) {
	t = new derived();
}
int main() {
	myPointer<based> p;		// ok, 일단 선언만으론 사용이 가능함
					// 또한 추상 클래스는 T* 형식을 통해 간접적으로 인스턴스의 포인터를 만들어낼 수 있음
	getFactory(&p);			// p의 연산자 오버로딩된 T*&를 통해 실제 T*  (based*) 에 derived 를 집어넣어줌
	(*p)->func1();			// ok
}

실제로 간단하게 구현된 abstract class의 정적 다형성과 Factory를 이용한 instance 생성

 

동적 다형성보다는 정적 다형성이 더 빠르다.

 

그런데 이를 정적 다형성이라 칭할 수 있는가 ?

 

동적 다형성은 같은 추상클래스를 상속하여 가상 함수를 타고 들어가는 것

정적 다형성은 <> 같은 옵션으로 다른 타입을 가지게 하는 것

위의 Factory 는 abstarct class 를 <> 의 option으로 사용하긴 하나, 가상 함수를 타고 들어가게 됨