차이점은 무엇이며
public
,private
그리고protected
상속 C ++는?
SO에서 찾은 모든 질문은 특정 사례를 처리합니다.
답변
이 질문에 대답하기 위해 먼저 회원의 접근자를 내 말로 설명하고 싶습니다. 이미 알고 있다면 “다음 :”으로 넘어가십시오.
거기에 제가 알고 세 가지 접근은 다음과 같습니다 public
, protected
그리고 private
.
허락하다:
class Base {
public:
int publicMember;
protected:
int protectedMember;
private:
int privateMember;
};
- 알고있는 모든 것은
Base
또한Base
포함하는 것을 알고 있습니다publicMember
. - 만 어린이들 (자녀)은 알고 있습니다
Base
포함되어 있습니다protectedMember
. - 아무도하지만
Base
알고 없습니다privateMember
.
“알다”는 것은 “존재 함을 인정하고 따라서 접근 할 수 있음”을 의미합니다.
다음:
공개, 개인 및 보호 된 상속에서도 마찬가지입니다. 에서 상속되는 클래스 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
하지 않습니다.
클래스의 멤버 / 친구 만 개인 상속을 볼 수 있으며 멤버 / 친구 및 파생 클래스 만 보호 된 상속을 볼 수 있습니다.
공공 상속
-
IS-A 상속. 버튼은 윈도우이며, 윈도우가 필요한 곳이면 버튼도 전달할 수 있습니다.
class button : public window { };
보호 된 상속
-
기간 내에 보호됩니다. 거의 유용하지 않습니다.
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! } };
개인 상속
-
이용 약관. 기본 클래스의 사용법은 파생 클래스를 구현하기위한 것입니다. 특성과 크기가 중요한 경우에 유용합니다 (함수 만 포함 된 빈 특성은 빈 기본 클래스 최적화를 사용합니다). 그러나 종종 격리 가 더 나은 솔루션입니다. 문자열의 크기는 매우 중요하므로 여기에서 자주 볼 수 있습니다.
template<typename StorageModel> struct string : private StorageModel { public: void realloc() { // uses inherited function StorageModel::realloc(); } };
공개 회원
-
골재
class pair { public: First first; Second second; };
-
접근 자
class window { public: int getWidth() const; };
보호 회원
-
파생 클래스에 대한 향상된 액세스 제공
class stack { protected: vector<element> c; }; class window { protected: void registerClass(window_descriptor w); };
개인 회원
-
구현 세부 사항 유지
class window { private: int width; };
C 스타일 캐스트는 정의 된 안전한 방식으로 파생 클래스를 보호 또는 개인 기본 클래스로 캐스트하고 다른 방향으로도 캐스트 할 수 있습니다. 구현 세부 사항에 따라 코드를 만들 수 있기 때문에 모든 비용을 피해야하지만 필요한 경우이 기술을 사용할 수 있습니다.
답변
이 세 키워드는 또한 완전히 다른 상황에서 가시성 상속 모델 을 지정하는 데 사용됩니다 .
이 테이블은 서브 클래스가 완전히 정의 될 때 컴포넌트에 대한 결과 액세스를 나타내는 컴포넌트 선언 및 상속 모델의 가능한 모든 조합을 수집합니다.
위의 표는 다음과 같이 해석됩니다 (첫 번째 행을보십시오).
구성 요소가되는 경우 선언 으로 대중 과 그 클래스가되어 상속 으로 공공 결과 액세스 입니다 공공 .
예를 들면 :
class Super {
public: int p;
private: int q;
protected: int r;
};
class Sub : private Super {};
class Subsub : public Sub {};
변수에 대한 결과 액세스 p
, q
, r
수업 시간에 Subsub는 없다 아무도 .
또 다른 예:
class Super {
private: int x;
protected: int y;
public: int z;
};
class Sub : protected Super {};
Sub 클래스의 변수 y
에 대한 결과 액세스 는 보호 되며 variable 에 대한 액세스 는 없습니다 .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;
}
명명 된 클래스의 서브 클래스 Super
또는 해당 Sub
클래스 의 서브 클래스 인 Sub이라는 정의 된 클래스는 클래스 에서 파생됩니다 Super
. 이 Sub
클래스는 새로운 변수 나 새로운 함수를 도입하지 않습니다. 그것은 Sub
클래스의 객체가 Super
클래스가 실제로 Super
클래스 객체 의 사본이 된 후에 모든 특성을 상속 한다는 것을 의미합니까 ?
없음 . 그렇지 않습니다.
다음 코드를 컴파일하면 컴파일 오류 put
와 get
메소드에 액세스 할 수 없다는 컴파일 오류 만 표시 됩니다. 왜?
가시성 지정자를 생략하면 컴파일러는 소위 개인 상속 을 적용한다고 가정합니다 . 이는 모든 퍼블릭 슈퍼 클래스 컴포넌트가 프라이빗 액세스 로 바뀌고 프라이빗 슈퍼 클래스 컴포넌트는 전혀 액세스 할 수 없음을 의미합니다. 따라서 서브 클래스 내에서 후자를 사용할 수 없음을 의미합니다.
우리는 이전에 사용 된 액세스 정책을 보존하고 싶다고 컴파일러에 알려야합니다.
class Sub : public Super { };
오해하지 마십시오 : 스토리지 변수와 같은 Super 클래스의 개인 구성 요소가 다소 마술적인 방식으로 공개 구성 요소로 바뀐다는 의미는 아닙니다. 비공개 구성 요소는 비공개로 유지 되며 공개
는 공개 상태로 유지 됩니다.
Sub
클래스의 객체는 클래스에서 생성 된 이전 형제와 같은 것을 “거의”수행 할 수 있습니다 Super
. “거의” 서브 클래스라는 사실은 클래스가 슈퍼 클래스의 개인 컴포넌트에 대한 액세스 권한을 상실 했음을 의미하기 때문 입니다. Sub
저장 변수를 직접 조작 할 수 있는 클래스 의 멤버 함수를 작성할 수 없습니다 .
이것은 매우 심각한 제한 사항입니다. 해결 방법이 있습니까?
예 .
세 번째 액세스 수준을 protected 라고 합니다. protected 키워드 는 서브 클래스에서 사용될 때이 컴포넌트로 표시된 컴포넌트 가 공용 컴포넌트 처럼 작동하며 다른 세계에서는 개인 컴포넌트 처럼 보입니다 . – 이 (우리의 예에서 슈퍼 클래스와 같은)만을 공개적으로 상속 클래스 마찬가지입니다 –
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
클래스에 대한 새로운 기능 이며 한 가지 중요한 작업 을 수행합니다. Super 클래스에서 스토리지 변수에 액세스합니다 .
변수가 private으로 선언되면 불가능합니다. 기본 함수 범위에서 변수는 어쨌든 숨겨져 있으므로 다음과 같이 작성하면 다음과 같습니다.
object.storage = 0;
컴파일러는 그것이임을 알려줍니다 error: 'int Super::storage' is protected
.
마지막으로 마지막 프로그램은 다음과 같은 출력을 생성합니다.
storage = 101
답변
기본 클래스의 공개 멤버가 파생 클래스에서 노출되는 방법과 관련이 있습니다.
- 공개-> 기본 클래스의 공개 멤버는 공개 (일반적으로 기본값)입니다.
- protected-> 기본 클래스의 공개 멤버가 보호됩니다
- 비공개-> 기본 클래스의 공개 멤버는 비공개입니다
litb가 지적했듯이 공개 상속은 대부분의 프로그래밍 언어에서 볼 수있는 전통적인 상속입니다. 그것은 “IS-A”관계를 모형화 한 것입니다. C ++ 특유의 AFAIK 인 사유 상속은 “기간 내에 구현 된”관계입니다. 즉 , 파생 클래스에서 공용 인터페이스 를 사용 하려고 하지만 파생 클래스의 사용자가 해당 인터페이스에 액세스하지 못하도록해야합니다. 많은 경우,이 경우 기본 클래스를 개인 기본으로 사용하는 대신 기본 클래스를 집계해야 기본 클래스의 기능을 재사용하기 위해 파생 된 멤버를 작성해야합니다.
답변
Member in base class : Private Protected Public
상속 유형 : 상속 된 객체 :
Private : Inaccessible Private Private
Protected : Inaccessible Protected Protected
Public : Inaccessible Protected Public
답변
1) 공공 상속 :
ㅏ. 파생 클래스에서는 기본 클래스의 비공개 멤버에 액세스 할 수 없습니다.
비. 기본 클래스의 보호 멤버는 파생 클래스에서 보호됩니다.
씨. 기본 클래스의 공개 멤버는 파생 클래스에서 공개로 유지됩니다.
따라서 다른 클래스는 파생 클래스 개체를 통해 Base 클래스의 공용 멤버를 사용할 수 있습니다.
2) 상속 상속 :
ㅏ. 파생 클래스에서는 기본 클래스의 비공개 멤버에 액세스 할 수 없습니다.
비. 기본 클래스의 보호 멤버는 파생 클래스에서 보호됩니다.
씨. Base 클래스의 공개 멤버도 파생 클래스의 보호 멤버가됩니다.
따라서 다른 클래스는 파생 클래스 개체를 통해 Base 클래스의 공용 멤버를 사용할 수 없습니다. 그러나 Derived의 서브 클래스에서 사용할 수 있습니다.
3) 개인 상속 :
ㅏ. 파생 클래스에서는 기본 클래스의 비공개 멤버에 액세스 할 수 없습니다.
비. 기본 클래스의 보호 및 공개 멤버는 파생 클래스의 개인 멤버가됩니다.
따라서 파생 클래스에서 개인 클래스이므로 파생 클래스 개체를 통해 다른 클래스에서 Base 클래스의 멤버에 액세스 할 수 없습니다. 따라서 파생 클래스의 하위 클래스조차도 액세스 할 수 없습니다.