상속 은하계로 진입했습니다
패시브 스킬 <다형성>을 습득했습니다. 도달도 3/20
패시브 스킬 <다형성>을 습득했습니다. 도달도 3/20
1.2. 이번에 배울 것 ¶
- 상속
○ public, private, protected
- 상속과 객체 생명주기
- virtual과 overriding
○ overriding 개념
○ virtual 선언
○ overloading된 메서드의 overriding
- 부모 클래스의 참조
- 서브클래스의 디폴트 대입 연산자, 복사 생성자
- 업 캐스팅과 다운 캐스팅
- pure virtual method와 abstract class
- virtual 소멸자
- vtable과 다형성의 원리
- 다중 상속과 virtual base class
- RTTI(Run-time type information)
- ★(C++11)상속 방지
- ★(C++11)오버라이딩 방지
- ★(C++11)override 키워드
- ★(C++11)생성자 상속
- (실습)상속 관계 디자인하기
- (실습)클래스 작성
2.2. 코드 ¶
- private, protected, public 상속
class TestClass { private: void privateDo(); protected: void protectedDo(); public: void publicDo(); }; class InheritencePrivate : private TestClass {}; // private보다 넓은 공유 범위를 가지는 것들을 private로 전환하여 상속 class InheritenceProtected : protected TestClass {}; // protected보다 넓은 공유 범위를 가지는 것들을 protected로 전환하여 상속 class InheritencePublic : public TestClass {}; // 그대로 상속 void main() { InheritencePrivate a; InheritenceProtected b; InheritencePublic c; a.privateDo(); a.protectedDo(); a.publicDo(); // 모두 컴파일 에러 b.privateDo(); b.protectedDo(); b.publicDo(); // 모두 컴파일 에러 c.privateDo(); c.protectedDo(); c.publicDo(); // publicDo 제외 컴파일 에러 }
- virtual과 overriding
#include <iostream> class TestClass { private: void privateDo(); protected: void protectedDo(); public: virtual void publicDo(); virtual void publicDo(int num); void publicDo_2(); }; class Inheritence : public TestClass { public: void publicDo(); void publicDo(int num); void publicDo_2(); }; void main() { Inheritence * inst = new Inheritence(); TestClass * tcInst = new TestClass(); inst->publicDo(); inst->publicDo_2(); TestClass * convertInst = new TestClass(); convertInst = (TestClass *) inst; convertInst->publicDo(); convertInst->publicDo_2(); // 다형성은 포인터 변수의 자료형을 기준으로 하며, virtual이 선언되어 있지 않으면 적용되지 않음. /* output Inheritence publicDo Inheritence publicDo_2 Inheritence publicDo TestClass publicDo_2 */ } void TestClass::publicDo() { std::cout << "TestClass publicDo" << std::endl; } void TestClass::publicDo(int num) { std::cout << "TestClass overloading publicDo" << std::endl; } void Inheritence::publicDo() { std::cout << "Inheritence publicDo" << std::endl; } void Inheritence::publicDo(int num) { std::cout << "Inheritence overloading publicDo" << std::endl; } void TestClass::publicDo_2() { std::cout << "TestClass publicDo_2" << std::endl; } void Inheritence::publicDo_2() { std::cout << "Inheritence publicDo_2" << std::endl; }
- 업 캐스팅과 다운 캐스팅
// 업 캐스팅이란 파생 클래스의 객체를 기본 클래스의 포인터로 가리키는 것을 말한다. // 다운 캐스팅이란 기본 클래스의 객체를 파생 클래스의 객체로 가리키는 것을 말한다. class Point { private: int x, y; public: void set(int x, int y); void showPoint(); }; class ColorPoint : public Point { private: string color; public: void setColor(string color); void showColorPoint(); }; void main(void) { ColorPoint cp; ColorPoint * pCp = &cp; Point * pP = pCp; // 업 캐스팅 Point * newPp = new Point(); ColorPoint * newPcP = (ColorPoint *) newPp; // 다운 캐스팅. 명시적으로만 가능하다. newPcP->showColorPoint(); // 컴파일 오류가 발생하지 않는다. 주의할 것. }
- 순수 가상 함수와 추상 클래스
class TestClass { private: void privateDo(); protected: void protectedDo(); public: virtual void publicDo() = 0; // 이 메서드는 순수 가상 함수로, 자식 클래스에서 반드시 재정의 virtual void publicDo(int num); void publicDo_2(); }; // 순수 가상 함수가 하나 이상있으면 추상 클래스 취급되어 인스턴스 생성 불가능
- 가상 소멸자
class TestClass { private: char * cString; public: TestClass() { cString = new char[20]; } virtual ~TestClass() { delete[] cString; } }; class Inheritence : public TestClass { private: int * intArr; public: Inheritence() { intArr = new int[20]; } ~Inheritence() { delete[] intArr; } }; // Inheritence에서 소멸자가 호출되지 않아 메모리가 누수될 가능성이 있기 때문에 가상 소멸자 사용
- 다중 상속과 virtual base class
class SuperClass { public: virtual void DoSomething(); }; class HalfSuperClass_1 : public virtual SuperClass { }; class HalfSuperClass_2 : public virtual SuperClass { }; class ChildClass : public HalfSuperClass_1, public HalfSuperClass_2 { }; void main(void) { ChildClass inst; inst.DoSomething(); } // SuperClass에 있는 함수를 사용하려 할 때, 모호성을 제거하기 위해서 상속 시 virtual 키워드를 통해 상속한다. // 컴파일러에게 파생 클래스의 객체가 생성될 때 기본 클래스의 멤버 공간을 오직 한 번만 할당하고, 이미 할당되어 있다면 그 공간을 // 공유하도록 함으로써, 가상 기본 클래스의 멤버 공간은 오직 한 번만 할당하는 것을 의미 // 다만, 이것 전에 다중 상속은 왠만해서 쓰지말자.
- 상속/오버라이드 방지 및 override 키워드
class TestClass final // 이럴 경우 상속 불가능 { private: void privateDo(); protected: void protectedDo(); public: virtual void publicDo() final; // 이럴 경우 오버라이딩 불가능 virtual void publicDo(int num); void publicDo_2(); }; class Inheritence : public TestClass { public: void publicDo(); void publicDo(int num) override; // override 한 것을 명시적으로 표현함 (매개 변수 등에서 에러가 날 경우 방지할 수 있음) void publicDo_2(); };
- 생성자 상속
class TestClass { public: TestClass(); TestClass(int num); }; class Inheritence : public TestClass { public: using TestClass::TestClass; /* 생성되는 것들 Inheritence(int num) : TestClass(num) {}; Inheritence() : TestClass() {}; */ }; void main() { Inheritence c(10); }