17.5 Inheritance and access specifiers

주홍영·2022년 3월 20일
0

Learncpp.com

목록 보기
166/199

https://www.learncpp.com/cpp-tutorial/inheritance-and-access-specifiers/

이번 섹션에서는 public, private, protected에서 자세하게 살펴볼 예정이다

우리는 public과 private이라는 access specifiers에 대해서 본적이 있다
빠르게 복습하자면 public member는 어디에서나 접근이 가능하고 private는 같은 클래스의 member function에서만 접근이 가능하다
따라서 derived class에서 base의 private member에 direct 접근이 불가능하다

The protected access specifier

protected access specifer는 friend와 derived class에서 접근할 수 있는 멤버이다
그러나 외부에서는 접근이 불가능하다

class Base
{
public:
    int m_public {}; // can be accessed by anybody
protected:
    int m_protected {}; // can be accessed by Base members, friends, and derived classes
private:
    int m_private {}; // can only be accessed by Base members and friends (but not derived classes)
};

class Derived: public Base
{
public:
    Derived()
    {
        m_public = 1; // allowed: can access public base members from derived class
        m_protected = 2; // allowed: can access protected base members from derived class
        m_private = 3; // not allowed: can not access private base members from derived class
    }
};

int main()
{
    Base base;
    base.m_public = 1; // allowed: can access public members from outside class
    base.m_protected = 2; // not allowed: can not access protected members from outside class
    base.m_private = 3; // not allowed: can not access private members from outside class

    return 0;
}

위의 예시를 보면 protected 멤버는 derived에서 접근이 가능하나 main같은 외부에서는 접근이 불가능함을 알 수 있다

So when should I use the protected access specifier?

protected의 속성은 derived class에서 direct 접근이 가능하다는 것이다
만약 base 뿐만이 아닌 derived에서도 변경을 할 가능성이 있다면 protected로 설정하는 것이다

So when should I use the protected access specifier?

상속에도 종류가 있다
public, protected, private 상속
우리가 만약 inheritance type을 명시하지 않는다면 default로 private 상속을 하게 된다

Public inheritance

class Base
{
public:
    int m_public {};
protected:
    int m_protected {};
private:
    int m_private {};
};

class Pub: public Base // note: public inheritance
{
    // Public inheritance means:
    // Public inherited members stay public (so m_public is treated as public)
    // Protected inherited members stay protected (so m_protected is treated as protected)
    // Private inherited members stay inaccessible (so m_private is inaccessible)
public:
    Pub()
    {
        m_public = 1; // okay: m_public was inherited as public
        m_protected = 2; // okay: m_protected was inherited as protected
        m_private = 3; // not okay: m_private is inaccessible from derived class
    }
};

int main()
{
    // Outside access uses the access specifiers of the class being accessed.
    Base base;
    base.m_public = 1; // okay: m_public is public in Base
    base.m_protected = 2; // not okay: m_protected is protected in Base
    base.m_private = 3; // not okay: m_private is private in Base

    Pub pub;
    pub.m_public = 1; // okay: m_public is public in Pub
    pub.m_protected = 2; // not okay: m_protected is protected in Pub
    pub.m_private = 3; // not okay: m_private is inaccessible in Pub

    return 0;
}

Protected inheritance

Private inheritance

class Base
{
public:
    int m_public {};
protected:
    int m_protected {};
private:
    int m_private {};
};

class Pri: private Base // note: private inheritance
{
    // Private inheritance means:
    // Public inherited members become private (so m_public is treated as private)
    // Protected inherited members become private (so m_protected is treated as private)
    // Private inherited members stay inaccessible (so m_private is inaccessible)
public:
    Pri()
    {
        m_public = 1; // okay: m_public is now private in Pri
        m_protected = 2; // okay: m_protected is now private in Pri
        m_private = 3; // not okay: derived classes can't access private members in the base class
    }
};

int main()
{
    // Outside access uses the access specifiers of the class being accessed.
    // In this case, the access specifiers of base.
    Base base;
    base.m_public = 1; // okay: m_public is public in Base
    base.m_protected = 2; // not okay: m_protected is protected in Base
    base.m_private = 3; // not okay: m_private is private in Base

    Pri pri;
    pri.m_public = 1; // not okay: m_public is now private in Pri
    pri.m_protected = 2; // not okay: m_protected is now private in Pri
    pri.m_private = 3; // not okay: m_private is inaccessible in Pri

    return 0;
}

A final example

class Base
{
public:
	int m_public {};
protected:
	int m_protected {};
private:
	int m_private {};
};

class D2 : private Base // note: private inheritance
{
	// Private inheritance means:
	// Public inherited members become private
	// Protected inherited members become private
	// Private inherited members stay inaccessible
public:
	int m_public2 {};
protected:
	int m_protected2 {};
private:
	int m_private2 {};
};

class D3 : public D2
{
	// Public inheritance means:
	// Public inherited members stay public
	// Protected inherited members stay protected
	// Private inherited members stay inaccessible
public:
	int m_public3 {};
protected:
	int m_protected3 {};
private:
	int m_private3 {};
};

위의 예시를 보면서 익혀보자

profile
청룡동거주민

0개의 댓글