17.8 Hiding inherited functionality

주홍영·2022년 3월 20일
0

Learncpp.com

목록 보기
169/199

https://www.learncpp.com/cpp-tutorial/hiding-inherited-functionality/

Changing an inherited member’s access level

C++은 우리가 child class에서 parent class의 member's access specifier를 수정할 수 있도록 하고 있다. 이는 using declaration을 통해 가능하게 하고 있다.
using을 derived class에서 access specifier하에서 하게되면 access specifier가 derived class에서 만큼은 수정되는 것이다

#include <iostream>

class Base
{
private:
    int m_value {};

public:
    Base(int value)
        : m_value { value }
    {
    }

protected:
    void printValue() const { std::cout << m_value; }
};

위의 Base에서 printValue()함수는 protected로 지정이 되어있다

따라서 이를 상속받을 Derived class에서 public 접근은 원래는 되지 않는다

class Derived: public Base
{
public:
    Derived(int value)
        : Base { value }
    {
    }

    // Base::printValue was inherited as protected, so the public has no access
    // But we're changing it to public via a using declaration
    using Base::printValue; // note: no parenthesis here
};

그런데 Derived의 public section에서 using Base::printValue를 통해 이 클래스에서는 public으로 간주하고 있다

int main()
{
    Derived derived { 7 };

    // printValue is public in Derived, so this is okay
    derived.printValue(); // prints 7
    return 0;
}

따라서 main함수에서 derived object의 member function 접근으로 printValue()를 사용할 수 있게 된 것이다

참고로 우리는 derived class에서 접근할 수 있는 member의 specifier만을 수정할 수 있다
따라서 Base에서 private 멤버는 아예 접근이 불가능하므로 protected나 public으로 수정할 수 없다

Hiding functionality

c++에서는 Base의 functionality를 지우거나 제한할 수 없다
유일한 방법은 소스코드를 수정하는 것이다
그러나 Derived class에서는 이를 hide하는 것이 가능하다

#include <iostream>
class Base
{
public:
	int m_value {};
};

class Derived : public Base
{
private:
	using Base::m_value;

public:
	Derived(int value)
	// We can't initialize m_value, since it's a Base member (Base must initialize it)
	{
		// But we can assign it a value
		m_value = value;
	}
};

int main()
{
	Derived derived { 7 };

	// The following won't work because m_value has been redefined as private
	std::cout << derived.m_value;

	return 0;
}

using을 이용해 private에서 선언함으로써 접근이 불가능하도록 만들고 있다
public 상속을 받았음에도 private로 hide 해서 main 함수에서 public 접근이 불가능하다

위의 방법말고도 다른방법이 있다

#include <iostream>
class Base
{
private:
	int m_value {};

public:
	Base(int value)
		: m_value { value }
	{
	}

	int getValue() const { return m_value; }
};

class Derived : public Base
{
public:
	Derived(int value)
		: Base { value }
	{
	}


	int getValue() = delete; // mark this function as inaccessible
};

int main()
{
	Derived derived { 7 };

	// The following won't work because getValue() has been deleted!
	std::cout << derived.getValue();

	return 0;
}

위의 코드를 보면 Derived class에서 int getValue() = delete; 를 통해
접근 불가로 마킹한 것이다

이는 Derived를 통한 접근이 불가능한 것이므로 upcasting을 이용해 다음과 같은 방법으로 접근이 가능하다

int main()
{
	Derived derived { 7 };

	// We can still access the function deleted in the Derived class through the Base class
	std::cout << static_cast<Base&>(derived).getValue();

	return 0;
}
profile
청룡동거주민

0개의 댓글