클라이언트가 을 다시 DLL로 전달하는 데 포인터를 사용할 필요가없는 한 앞으로 선언을 사용할 수 있습니다. 불완전한 유형에서 파생 될 수 없습니다. (최근에 비슷한 케이스에 직면했을 때 나는 돼지 고기를 다 먹었고 을 기준으로 을 특수 포장 형식으로 설계했습니다. 인터페이스 코드에 캐스팅이 많이 있지만, 클라이언트가 값은 날입니다.)
해당 클래스가 클라이언트가 사용해야하는 인터페이스를 구현하는 경우 도 두 가지 해결책이 있습니다. 첫 번째는 이것을 변경하는 것입니다. 각 멤버 함수를 에 포인터를 사용하는 자유 함수로 바꾸고 앞으로 선언 만하면됩니다. ClientVisibleInterface
에서 직접 파생 이 가능하지만, 그것은 불가능 최초의 :
class InternallyVisibleInterface : public ClientVisibleInterface
{
protected:
InternallyVisibleInterface() {}
// And anything else you need. If there is only one class in
// your application which should derive from the interface,
// this is it. If there are several, they should derive from
// this class, rather than ClientVisibleInterface, since this
// is the only class which can construct the
// ClientVisibleInterface base class.
};
void ClientVisibleInterface::something()
{
assert(dynamic_cast<InternallyVisibleInterface*>(this) != nullptr);
doSomething();
}
이 두 가지 수준의 보호를 제공합니다
class InternallyVisibleInterface;
class ClientVisibleInterface
{
private:
virtual void doSomething() = 0;
ClientVisibleInterface() = default;
friend class InternallyVisibleInterface;
protected: // Or public, depending on whether the client should
// be able to delete instances or not.
virtual ~ClientVisibleInterface() = default;
public:
void something();
};
하고 DLL에서 다음 두 번째는 같은 것을 사용하는 것입니다 결과 클래스는 생성자를 가지므로 을 인스턴스화 할 수 없습니다. 둘째, 클라이언트 코드가 어떻게 든 속이면 런타임 오류가 발생합니다.
두 보호가 모두 필요하지 않을 수도 있습니다. 하나 또는 다른 사람 충분해야합니다. 개인 생성자는 런타임 오류가 아닌 컴파일 시간 오류 이됩니다. 반면에, 그것 없이는 은 분산 헤더에 InternallyVisibleInterface
의 이름을 언급 할 필요조차 없습니다.
[C++ 11에는 최종 키워드가 있습니다.] (http://en.cppreference.com/w/cpp/language/final) – Borgleader
... final final? – Wintermute
핵심 문제는 자신의 구현에서 서브 클래 싱해야 할 필요가 있다는 것입니다. 따라서 기본적으로 구현자는 호출자와 다른 선언을보아야합니다. (예 : '최종'또는 사설 CTor). reinterpret_cast를 사용하여 대부분의 구현에서 가능 합니다만, 한계 이익을 지닌 추한 해킹이 될 것이므로 필자는 반대합니다. – peterchen