문제

의 차이는 무엇입 public, private, 고 protected 는 상속에서는 C++?의 모든 질문에 그래서 다루는 특별한 경우.

도움이 되었습니까?

해결책

그 질문에 대답하기 위해, 나는 먼저 내 말로 회원의 접근자를 설명하고 싶습니다. 이미 이것을 알고 있다면 "다음 :"제목으로 건너 뛰십시오.

내가 알고있는 세 가지 액세서가 있습니다. public, protected 그리고 private.

허락하다:

class Base {
    public:
        int publicMember;
    protected:
        int protectedMember;
    private:
        int privateMember;
};
  • 알고있는 모든 것 Base 또한 알고 있습니다 Base 포함 publicMember.
  • 아이들 (그리고 그들의 자녀들)만이 Base 포함 protectedMember.
  • 아무도 없어요 Base 알고 있습니다 privateMember.

"Is Apher of"라는 말은 "존재를 인정하여 접근 할 수 있다는 것을 의미합니다."

다음:

공공, 민간 및 보호 된 상속도 마찬가지입니다. 수업을 고려해 봅시다 Base 그리고 수업 Child 그게 상속됩니다 Base.

  • 상속이있는 경우 public, 알고있는 모든 것 Base 그리고 Child 또한 알고 있습니다 Child 상속 Base.
  • 상속이있는 경우 protected, 뿐 Child, 그리고 그 아이들은 그들이 Base.
  • 상속이있는 경우 private, 다른 사람은 없습니다 Child 상속을 알고 있습니다.

다른 팁

class A 
{
public:
    int x;
protected:
    int y;
private:
    int z;
};

class B : public A
{
    // x is public
    // y is protected
    // z is not accessible from B
};

class C : protected A
{
    // x is protected
    // y is protected
    // z is not accessible from C
};

class D : private A    // 'private' is default for classes
{
    // x is private
    // y is private
    // z is not accessible from D
};

중요 참고 : 클래스 B, C 및 D에는 모두 변수 x, y 및 z를 포함합니다. 접근 문제 일뿐입니다.

보호 및 개인 상속의 사용에 대해 읽을 수 있습니다. 여기.

가시성을 제한하는 상속의 것 코드를 볼 수 없는 클래스를 상속 다른 클래스:암시적 변환에서 유래를 베이스 작동하지 않을 것,그리고 static_cast 베이스에서 파생 중 하나가 작동하지 않습니다.

만원/의 친구 클래스를 볼 수 있는 개인 상속,그리고 회원들만 친구와 파생된 클래스를 볼 수있는 보호되는 상속입니다.

공개

  1. 입니다-상속입니다.버튼이-창,어디서나는 창,필요한 버튼을 전달할 수 있도.

    class button : public window { };
    

  1. 보호 구현 약관-습니다.거의 유용합니다.에서 사용되는 boost::compressed_pair 에서 파생 빈 클래스고 저장 메모리를 사용하여 빈 기본 클래스 최적화(아래 예를 사용하지 않는 템플릿을 유지하는 시점에서):

    struct empty_pair_impl : protected empty_class_1 
    { non_empty_class_2 second; };
    
    struct pair : private empty_pair_impl {
      non_empty_class_2 &second() {
        return this->second;
      }
    
      empty_class_1 &first() {
        return *this; // notice we return *this!
      }
    };
    

private

  1. 구현 약관-습니다.사용법의 기본 클래스만을 구현하기 위한 파생된 클래스입니다.유용한 특성과는 경우 크기(비적 특성만 포함하는 기능이 사용하는 빈 기본 클래스 최적화).주 격리 은 더 나은 솔루션,하지만.크기 위한 문자열은 중요한,그래서 종종 보이 여기 사용

    template<typename StorageModel>
    struct string : private StorageModel {
    public:
      void realloc() {
        // uses inherited function
        StorageModel::realloc();
      }
    };
    

공개

  1. 집계

    class pair {
    public:
      First first;
      Second second;
    };
    
  2. 접근

    class window {
    public:
        int getWidth() const;
    };
    

  1. 제공하는 향상에 대한 액세스 클래스 파생

    class stack {
    protected:
      vector<element> c;
    };
    
    class window {
    protected:
      void registerClass(window_descriptor w);
    };
    

private

  1. 유지 구현 정보

    class window {
    private:
      int width;
    };
    

참고는 C 스타일의 캐스팅을 의도적으로 캐스팅할 수 있습래된 클래스 보호 또는 개인의 기본 클래스에 정의하고 안전한 방법으로 캐스팅으로 다른 방향으로 너무입니다.이 피해야한 모든 비용에 할 수 있기 때문에 코드에 따라 구현 정보-그러나 필요한 경우,당신은 당신을 사용할 수 있습니다.

기본 클래스의 공개 구성원이 파생 클래스에서 노출되는 방식과 관련이 있습니다.

  • Public-> Base Class의 공개 회원은 공개됩니다 (일반적으로 기본값)
  • 보호 -> 기본 클래스의 공개 회원은 보호됩니다.
  • Private-> Base Class의 공개 회원은 개인입니다.

Litb가 지적했듯이, 공개 상속은 대부분의 프로그래밍 언어에서 볼 수있는 전통적인 상속입니다. 그것이 "IS-A"관계를 모델링합니다. C ++에 특이한 Afaik의 개인 상속은 "관계에서 구현 된"관계입니다. 그것은 당신이 원하는 것입니다 사용 파생 클래스의 공개 인터페이스이지만 파생 클래스 사용자가 해당 인터페이스에 액세스하기를 원하지 않습니다. 많은 사람들은이 경우 기본 클래스를 집계해야한다고 주장합니다. 즉, 기본 클래스를 개인 기반으로 사용하는 대신 기본 클래스의 기능을 재사용하기 위해 파생 된 구성원을 만들어냅니다.

이 세 가지 키워드는 완전히 다른 컨텍스트에서 사용하여 가시성 상속 모델.

이 테이블은 서브 클래스가 완전히 정의 될 때 구성 요소에 대한 결과 액세스를 나타내는 구성 요소 선언 및 상속 모델의 가능한 모든 조합을 수집합니다.

enter image description here

위의 표는 다음과 같은 방식으로 해석됩니다 (첫 번째 행을보십시오).

구성 요소 인 경우 선언 ~처럼 공공의 그리고 그 수업입니다 상속 ~처럼 공공의 결과 입장 ~이다 공공의.

An example:

 class Super {
    public:      int p;
    private:     int q;
    protected:   int r;
 };

 class Sub : private Super {};

 class Subsub : public Sub {};

변수에 대한 결과 액세스 p, q, r 클래스 서브 서브 ~이다 없음.

또 다른 예:

class Super {
    private:     int x;
    protected:   int y;
    public:      int z;
 };
class Sub : protected Super {};

변수에 대한 결과 액세스 y, z 클래스 보결 ~이다 보호 그리고 변수 x ~이다 없음.

더 자세한 예 :

class Super {
private:
    int storage;
public:
    void put(int val) { storage = val;  }
    int  get(void)    { return storage; }
};
int main(void) {
    Super object;

    object.put(100);
    object.put(object.get());
    cout << object.get() << endl;
    return 0;
}

이제 서브 클래스를 정의하겠습니다.

class Sub : Super { };

int main(void) {
    Sub object;

    object.put(100);
    object.put(object.get());
    cout << object.get() << endl;
    return 0;
}

이름이 지정된 클래스의 서브 클래스 인 Sub라는 정의 된 클래스 Super 또는 Sub 클래스는에서 파생됩니다 Super 수업. 그만큼 Sub 클래스는 새로운 변수 나 새로운 기능을 도입하지 않습니다. 그것은 모든 대상을 의미합니까 Sub 클래스는 다음과 같은 모든 특성을 상속합니다 Super 클래스는 실제로 a의 사본입니다 Super 클래스의 개체?

아니. 그렇지 않습니다.

다음 코드를 컴파일하면 컴파일 오류만으로는 put 그리고 get 방법은 액세스 할 수 없습니다. 왜요?

가시성 지정자를 생략하면 컴파일러는 소위를 적용 할 것이라고 가정합니다. 개인 상속. 그것은 모두를 의미합니다 공공의 슈퍼 클래스 구성 요소가 변합니다 사적인 액세스, 개인 슈퍼 클래스 구성 요소는 전혀 액세스 할 수 없습니다. 결과적으로 서브 클래스 내부에서 후자를 사용할 수 없다는 것을 의미합니다.

우리는 이전에 사용 된 액세스 정책을 보존하고자한다는 것을 컴파일러에게 알릴 필요가 있습니다.

class Sub : public Super { };

오해하지 마십시오: 슈퍼 클래스의 개인 구성 요소 (스토리지 변수와 같은)가 다소 마술적인 방식으로 공개 구성 요소로 변하는 것은 아닙니다. 사적인 구성 요소는 남아 있습니다 사적인, 공공의남아있을 것입니다 공공의.

의 대상 Sub 수업은 Super 수업. "거의" 서브 클래스라는 사실은 또한 수퍼 클래스의 개인 구성 요소에 대한 클래스 손실. 우리는 회원 기능을 쓸 수 없습니다 Sub 스토리지 변수를 직접 조작 할 수있는 클래스.

이것은 매우 심각한 제한입니다. 해결 방법이 있습니까?

.

세 번째 액세스 레벨이 호출됩니다 보호. 보호 된 키워드는 구성 요소가 표시되어 있음을 의미합니다. 하위 클래스에서 사용될 때 공개적으로 행동하고 세계의 다른 지역에 대한 사적인 사람처럼 보입니다.. -- 이것은 공개적으로 상속 된 클래스에만 해당됩니다 (예 : 우리 예에서 슈퍼 클래스와 같은) --

class Super {
protected:
    int storage;
public:
    void put(int val) { storage = val;  }
    int  get(void)    { return storage; }
};

class Sub : public Super {
public:
    void print(void) {cout << "storage = " << storage;}
};

int main(void) {
    Sub object;

    object.put(100);
    object.put(object.get() + 1);
    object.print();
    return 0;
}

예제 코드에서 볼 수 있듯이 우리는 새로운 기능을 Sub 수업과 그것은 하나의 중요한 일을합니다. 슈퍼 클래스에서 스토리지 변수에 액세스합니다.

변수가 비공개로 선언 된 경우에는 불가능합니다. 기본 함수 범위에서 변수는 어쨌든 숨겨져 있으므로 다음과 같은 것을 쓰면

object.storage = 0;

컴파일러는 그것이 an임을 알려줍니다 error: 'int Super::storage' is protected.

마지막으로 마지막 프로그램은 다음 출력을 생성합니다.

storage = 101
Member in base class : Private   Protected   Public   

상속 유형 :             물체가 상속됩니다:

Private            :   Inaccessible   Private     Private   
Protected          :   Inaccessible   Protected   Protected  
Public             :   Inaccessible   Protected   Public

1) 공개 상속:

ㅏ. 기본 클래스의 개인 구성원은 파생 클래스에서 액세스 할 수 없습니다.

비. 기본 클래스의 보호 된 구성원은 파생 클래스에서 보호됩니다.

씨. 기본 클래스의 공개 구성원은 파생 클래스에서 공개적으로 남아 있습니다.

따라서 다른 클래스는 파생 클래스 객체를 통해 기본 클래스의 공개 구성원을 사용할 수 있습니다.

2) 보호 된 상속:

ㅏ. 기본 클래스의 개인 구성원은 파생 클래스에서 액세스 할 수 없습니다.

비. 기본 클래스의 보호 된 구성원은 파생 클래스에서 보호됩니다.

씨. 기본 클래스의 공개 구성원도 파생 클래스의 보호 된 구성원이됩니다.

따라서 다른 클래스는 파생 클래스 객체를 통해 기본 클래스의 공개 멤버를 사용할 수 없습니다. 그러나 파생의 서브 클래스가 가능합니다.

3) 개인 상속:

ㅏ. 기본 클래스의 개인 구성원은 파생 클래스에서 액세스 할 수 없습니다.

비. 기본 클래스의 보호 및 공개 구성원은 파생 계급의 개인 구성원이됩니다.

따라서 파생 클래스 객체에서 파생 클래스 객체를 통해 다른 클래스에서 기본 클래스의 구성원에게 액세스 할 수 없습니다. 따라서 파생 클래스의 서브 클래스조차도 액세스 할 수 없습니다.

공개 상속은 IS-A 관계를 모델링합니다. 와 함께

class B {};
class D : public B {};

모든 D a B.

개인 상속은 IS-Implemented-Ousing 관계 (또는 그에 대한 이름)를 모델링합니다. 와 함께

class B {};
class D : private B {};

D ~이다 ~ 아니다B, 그러나 모든 D 그것의 사용 B 구현에서. 대신 격리를 사용하여 개인 상속을 항상 제거 할 수 있습니다.

class B {};
class D {
  private: 
    B b_;
};

이것 D, 또한 사용하여 구현할 수 있습니다 B, 이 경우 ITS를 사용합니다 b_. 격리는 상속보다 유형간에 덜 단단한 커플 링이므로 일반적으로 선호해야합니다. 때로는 개인 상속 대신 격리를 사용하는 것이 개인 상속만큼 편리하지 않습니다. 종종 그것은 게으른 것에 대한 절름발이 변명입니다.

나는 아무도 무엇을 알고 있다고 생각하지 않습니다 protected 상속 모델. 적어도 나는 아직 설득력있는 설명을 보지 못했습니다.

다른 클래스에서 공개적으로 상속하면 모든 사람이 자신이 상속하고 있다는 것을 알고 있으며 기본 클래스 포인터를 통해 누구나 다형적으로 사용할 수 있습니다.

당신이 보호 적으로 상속된다면 당신의 자녀 수업 만 당신을 다형성으로 사용할 수 있습니다.

개인적으로 물려 받으면 자신만이 부모 수업 방법을 실행할 수 있습니다.

기본적으로 나머지 수업이 부모 수업과의 관계에 관한 지식을 상징합니다.

보호된 데이터 구성원에 액세스할 수 있는 모든 상속받은 클래스에서 당신의 클래스입니다.개인 데이터 멤버들,그러나 할 수 없습니다.이제 우리는 다음과 같다:

class MyClass {
    private:
        int myPrivateMember;    // lol
    protected:
        int myProtectedMember;
};

에서 확장자를 이 클래스를 참조 this.myPrivateMember 이 작동하지 않습니다.그러나, this.myProtectedMember 니다.값은 여전히 캡슐화,그렇다면 우리는 우리의 인스턴스화 이라는 클래스 myObj, 다음 myObj.myProtectedMember 작동하지 않습니다,그래서 그것은 비슷한 기능은 개인 데이터 구성원입니다.

Accessors    | Base Class | Derived Class | World
—————————————+————————————+———————————————+———————
public       |      y     |       y       |   y
—————————————+————————————+———————————————+———————
protected    |      y     |       y       |   n
—————————————+————————————+———————————————+———————
private      |            |               |    
  or         |      y     |       n       |   n
no accessor  |            |               |

y: accessible
n: not accessible

기반 이것 Java의 예 ... 천 단어의 가치가있는 작은 테이블을 생각합니다 :)

요약:

  • 개인 : 수업 내에서는 아무도 볼 수 없습니다.
  • 보호 : 개인 + 파생 클래스가 볼 수 있습니다
  • 대중 : 세상은 그것을 볼 수 있습니다

상속 할 때 (일부 언어로) 특정 방향으로 보호 유형의 보호 유형을 보호에서 공개로 변경할 수 있습니다.

사적인:

기본 클래스의 개인 구성원은 해당 기본 클래스의 구성원 만 액세스 할 수 있습니다.

공공의:

기본 클래스의 공개 구성원은 해당 기본 클래스의 구성원, 파생 클래스의 구성원 및 기본 클래스 및 파생 클래스 외부의 구성원이 액세스 할 수 있습니다.

보호 :

기본 클래스의 보호 된 구성원은 기본 클래스 회원과 파생 클래스의 구성원이 액세스 할 수 있습니다.


요컨대 :

사적인:베이스

보호:베이스 + 파생

공공의: 기본 + 파생 + 다른 멤버

나는 쉬운 답변을 찾았으므로 미래의 참조를 위해 게시 할 생각을했습니다.

링크에서 http://www.learncpp.com/cpp-tutorial/115-inheritance-and-access-specifiers/

class Base
{
public:
    int m_nPublic; // can be accessed by anybody
private:
    int m_nPrivate; // can only be accessed by Base member functions (but not derived classes)
protected:
    int m_nProtected; // can be accessed by Base member functions, or derived classes.
};

class Derived: public Base
{
public:
    Derived()
    {
        // Derived's access to Base members is not influenced by the type of inheritance used,
        // so the following is always true:

        m_nPublic = 1; // allowed: can access public base members from derived class
        m_nPrivate = 2; // not allowed: can not access private base members from derived class
        m_nProtected = 3; // allowed: can access protected base members from derived class
    }
};

int main()
{
    Base cBase;
    cBase.m_nPublic = 1; // allowed: can access public members from outside class
    cBase.m_nPrivate = 2; // not allowed: can not access private members from outside class
    cBase.m_nProtected = 3; // not allowed: can not access protected members from outside class
}

기본적으로 파생 클래스에서 기본 클래스의 대중 및 보호 된 구성원의 액세스 보호입니다. 공개 상속을 통해 파생 계급은 기지의 공개 및 보호 된 구성원을 볼 수 있습니다. 개인 상속으로, 그것은 할 수 없습니다. 보호를 받으면 파생 된 클래스와 그로부터 파생 된 클래스는 그것들을 볼 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top