개체가 선택적 기능을 제공하기 위해 인터페이스를 구현할 수있는 간단한 개체 모델로 작업하고 있습니다. 핵심은 객체가 (고유 한) 인터페이스 ID가 부여 된 getInterface
메소드를 구현해야한다는 것입니다. 그런 다음 메서드는 인터페이스에 대한 포인터를 반환하거나 객체가 요청 된 인터페이스를 구현하지 못하는 경우 null을 반환합니다. 클라이언트가 단지를 구현해야 있도록이 유형 목록 기반 클래스 계층 생성 코드의 대안은 무엇입니까?
struct Interface { };
struct FooInterface : public Interface { enum { Id = 1 }; virtual void doFoo() = 0; };
struct BarInterface : public Interface { enum { Id = 2 }; virtual void doBar() = 0; };
struct YoyoInterface : public Interface { enum { Id = 3 }; virtual void doYoyo() = 0; };
struct Object {
virtual Interface *getInterface(int id) { return 0; }
};
이 프레임 워크에서 작동 고객을위한 쉬운 것들, 내가 자동으로 'getInterface'구현을 생성하는 작은 템플릿을 사용하고 만들려면 : 다음은이를 설명하기 위해 코드 스케치입니다 인터페이스에 필요한 실제 기능. 아이디어는 Object
과 모든 인터페이스에서 구체적인 유형을 파생시킨 다음 getInterface
이 포인터를 this
(올바른 유형으로 캐스트)으로 반환하도록합니다. 다음은 템플릿과 데모 사용이다 : 이것은 아주 잘 작동
struct NullType { };
template <class T, class U>
struct TypeList {
typedef T Head;
typedef U Tail;
};
template <class Base, class IfaceList>
class ObjectWithIface :
public ObjectWithIface<Base, typename IfaceList::Tail>,
public IfaceList::Head
{
public:
virtual Interface *getInterface(int id) {
if (id == IfaceList::Head::Id) {
return static_cast<IfaceList::Head *>(this);
}
return ObjectWithIface<Base, IfaceList::Tail>::getInterface(id);
}
};
template <class Base>
class ObjectWithIface<Base, NullType> : public Base
{
public:
virtual Interface *getInterface(int id) {
return Base::getInterface(id);
}
};
class MyObjectWithFooAndBar : public ObjectWithIface< Object, TypeList<FooInterface, TypeList<BarInterface, NullType> > >
{
public:
// We get the getInterface() implementation for free from ObjectWithIface
virtual void doFoo() { }
virtual void doBar() { }
};
,하지만 못생긴 두 가지 문제가있다 :
나를 위해 차단기이 (MSVC6 작동하지 않는다는 것입니다 템플릿에 대한 지원이 좋지 않지만 불행하게도 저는 그것을 지원해야합니다.) 이 컴파일시 MSVC6에서 C1202 오류가 발생합니다.
재귀적인
ObjectWithIface
템플릿에 의해 모든 범위의 클래스 (선형 계층 구조)가 생성됩니다. 이것은 본인에게 문제가 아니지만 유감스럽게도 인터페이스 ID를getInterface
의 포인터에 매핑하기 위해 단일 문을 사용할 수는 없습니다. 대신 계층 구조의 각 단계는 단일 인터페이스를 확인한 다음 요청을 기본 클래스로 전달합니다.
이 상황을 개선하는 방법에 대한 의견이 있으십니까? 위의 두 가지 문제를 ObjectWithIface
템플릿으로 수정하거나 Object/Interface 프레임 워크를보다 쉽게 사용할 수있는 대안을 제안하십시오.
VC6을 지원해야하는 경우 템플리트 메타 프로그래밍 측면에서 귀하의 옵션이 제한적이라고 생각합니다. – jalf
@ jalf : 저는 분명히 제한되어 있습니다, 그렇습니다 - 나는이 한계 내에서 개선을 기대하고있었습니다. : -] –