2017-11-30 23 views
1

클래스로 사용 되더라도 "내"코드 만 클래스를 사용할 수 있도록하려면 어떻게해야합니까? 내 클래스 중 하나에 대한 기본 클래스의 사용을 표시하려면개인 기본 클래스로 사용되는 클래스의 공개 사용 금지

(이 기본 클래스로 사용되지 만약 내가 내 클래스 중 하나의 private 또는 protected 중첩 클래스를 만들 수있는 것은) 단순한 구현 세부입니다 나는 개인 기본 클래스 사용할 수 있습니다 : 나는 Base 클래스를 사용하는 것으로, 내 Derived 클래스의 클라이언트에

class Base 
{ 
     ... 
} 

class Derived: private Base 
{ 
public: 

     Derived(...): Base{...} {... }; 

     ... 
} 

것은 명백한되지 않습니다 :

#include "Derived.h" 

void client() { 
    Derived d{...}; 
    Base *b = static_cast< Base * >(&d);// error 
    ... 
} 

하지만 상상 그,214,클래스가 너무 특수하거나 혼란 스럽거나 사용하기 까다 롭다. 내 코드 클라이언트가 기본 클래스로 사용하거나 해당 클래스의 객체를 만들 수 없기를 바란다.

#include "Derived.h" 

class Client: Base// error wanted here 
{ 
public: 
    Client(...): Base{...} {...}; 

    ... 
} 

void client() 
{ 
    Derived d{...};// OK 
    Base b{...};// error wanted here 
    Client c{...};// error wanted here 
} 

내가 어떻게 할 수 있습니다

이 같은 클라이언트 코드가 실패, 그래서 나는 내 코드의 일부, 그것은 어떤 의미에서, "개인"되고 싶어?

실제로 동일한 "패키지"(모듈)의 다른 클래스에만 액세스 할 수 있지만 "패키지"외부 코드에서는 사용할 수없는 Java's package-private classes과 같은 것을 얻을 수 있는지 묻습니다.

답변

3

"개인"엔티티를 detail 네임 스페이스에 배치하여 규칙에 따라 "적용"할 수 있습니다. 많은 인기 라이브러리 (예 : 부스트) 다음을 수행

namespace detail 
{ 
    class Base { /* ... */ }; 
} 

class Derived : private detail::Base 
{ 
    /* ... */ 
}; 
모듈이 문제는 사용자가 제어 할 수있을 것 같은, 적절하게 해결 될 것 표준화됩니다

기관은 수출 어떤 것들을 구현입니다받을 것 세부.

+1

확실히 여기 있습니다. 멈추는 사람들은 어리석은 행동을하지 않습니다. 더 나은 것은 그들이 어리 석다는 것과 책임감있는 성인이되도록 남겨 두는 것입니다. – StoryTeller

+0

이렇게하면 아무 것도 얻을 수 없습니다. 클라이언트는'detail :: Base b = {...};'라고 쓸 수 있습니다. – Raedwald

+3

@ Raedwald : 더 좋은 해결책은 없습니다. C++ 개발자는 관습에 따라'detail ::'라고 쓰면 모든 내기가 꺼져 있음을 알아야합니다. 'libstdC++'에서 이상한 구현 실체를 사용하는 것을 막을 수있는 방법은 없습니다. –

2

Java에서하는 것처럼 직접 수행 할 수 없습니다. 대신 당신이 정말로 다음 그것의 Base 사용의 가능성을 방지하려면

namespace hidden { 
    class Base { 
    .. 
    }; 
} 

class Derived : private hidden::Base { 
    ... 
}; 

: 그것은 혼란을 피하는의 문제라면 당신은 당신의 코드의 클라이언트에 의해 무시 의미 네임 스페이스, 예를 들어 내부 Base를 이동할 수 있습니다 Base을 여러 클래스의 부모로 사용할 계획 인 경우 시간이 지남에 따라 달라질 수 있습니다. 당신은 Baseprivate 생성자를 제공하고 파생 클래스의 각이 있음을 나타낼 수 friendBase의 : 이것은 당신이 Base에서 파생 할 각 새로운 종류의 수동 유지 보수가 필요 물론

class Hider { 
    private: 
    Hider() = delete; 
    class Base { 
     .. 
    }; 

    friend class Derived; 
}; 

class Derived : Hider::Base { 
    .. 
}; 

.

+0

어떤 이유로 든 기본 클래스를 다른 클래스의 비공개 멤버로 만들 수 없습니다. 그런 다음 그것을 사용하는 친구 물건? – UKMonkey

+0

@UK 몽키 어떻게 그 수업을 숨길 수 있습니까? – Ivan

+0

@ 아이반 왜 '컨테이너'클래스가 숨겨져 있는지 신경 써야합니까? 누군가가 인스턴스를 만들려고하면 컴파일 오류가 발생하도록 만들 수 있습니다. – UKMonkey

1

당신이 100 %를 적용하려면 다음 나는이 전화의 사용자 포트 믿는다 " '_'로 시작하는 물건을 사용하지 마십시오"의 파이썬 방법이 마음에 들지 않으면 :

class Dave; 

class MyPrivateBaseClasses { 
    private: 
    MyPrivateBaseClasses(); // ensure nothing can use this class 
    class BaseClassA {}; 

    friend Dave; 
}; 

class Dave : public/private MyPrivateBaseClasses::BaseClassA 
{}; 

확실히 - 친구에게 사용하고 싶은 모든 것을 갖추어야한다는 것을 의미합니다.하지만 원하는 것을 정확히 제공합니다. BaseClassA를 사용하는 사람들에 대한 100 % 보호.

+0

최종 사용자 프로그래머가 자신의 유형을 시스템에 추가하는 것처럼 여전히 악의적 인 것을 막을 수는 없습니다. 명부. 솔직히 내가 생각할 수있는 유일하게 실제적인 보호는 숨겨진 기본 클래스의 소스를 배포하지 않는 것입니다.하지만 이는 실현 가능하지 않을 수 있으며 보호해야 할 악의적 인 수준에 따라 충분하지 않을 수도 있습니다. 물론, 나는 당신이 그 정도의 악의적 인 것을 막아야 할 필요가 있다면, 누군가 다른 사람에게 컴파일을 위해 소스를 배포하는 것을 무엇이라고 말하고 싶습니까? – SoronelHaetir

+0

글쎄, 사람들이 코드를 편집하는 것을 막지는 못하지만 코드를 편집하지 않고 사람들이 코드를 전혀 사용하지 못하게합니다. 다른 대답에 따라 네임 스페이스를 사용하려면 클래스를 사용하기 위해 코드를 편집 할 필요가 없습니다. – UKMonkey