티스토리 뷰
반응형
상속의 생존주기
- 일반적인 상속의 생존주기
#include <iostream> class Base { public: Base() { std::cout << "Base()" << std::endl; } ~Base() { std::cout << "~Base()" << std::endl; } }; class Derived : public Base { public: Derived() { std::cout << "Derived()" << std::endl; } ~Derived() { std::cout << "~Derived()" << std::endl; } }; int main() { Derived d; return 0; }
Base() Derived() ~Derived() ~Base()
- Up-casting 생존주기
#include <iostream> class Base { public: Base() { std::cout << "Base()" << std::endl; } ~Base() { std::cout << "~Base()" << std::endl; } }; class Derived : public Base { public: Derived() { std::cout << "Derived()" << std::endl; } ~Derived() { std::cout << "~Derived()" << std::endl; } }; int main() { Base* b = new Derived(); delete b; return 0; }
Base() Derived() ~Base()
상위 클래스의 소멸자만 호출되었다. 다음의 경우에서 문제가 될 수 있다.
class Derived : public Base { private: int* value = new int; // Never released public: Derived() { std::cout << "Derived()" << std::endl; } ~Derived() { std::cout << "~Derived()" << std::endl; delete value; } };
Derived의 소멸자가 호출되지 않아 할당된 value가 해제되지 않는다.
가상함수
- Base에서 함수가 존재할 수도 그렇지 않을 수도 있어야할 때 virtual 기호를 사용한다.이렇게 선언된 함수는 Derived의 함수를 가리지 않는다.
#include <iostream> class Base { public: virtual void say() { std::cout << "Hello" << std::endl; } }; class Derived : public Base { public: void say() override { std::cout << "World" << std::endl; } }; int main() { Derived d; Base& b = d; b.say(); return 0; }
World
상위 클래스의 함수에 virtual 기호를 붙여 하위 클래스의 함수 재정의를 가리지 않도록 한 예시이다. 재정의하는 하위 클래스의 함수에서는 override 기호를 붙여 virtual로 선언된 상위 클래스의 함수를 재정의했음을 명시적으로 나타낼 수 있다.
참조가 사용되는 이유는 복사 생성자를 이용한 복사의 경우 Derived의 데이터가 유실되어 Base의 새 객체를 만드는 것이지만, 참조를 사용하여 새 Base 객체 생성을 방지하고 Derived 있는 그대로의 주소만 가져다 사용하는 것이다. 하지만 이 경우에도 Base에는 없지만 Derived에 새로 추가된 함수를 사용할 수는 없고 Base에 정의된 함수만을 사용할 수 있다.class Derived : public Base { public: void say() override { std::cout << "World" << std::endl; } void foo() { std::cout << "FOO" << std::endl; } }; int main() { Derived d; Base& b = d; b.say(); b.foo(); // error: ‘class Base’ has no member named ‘foo’ return 0; }
참조를 사용하지 않고 pointer를 이용한 동적할당의 경우도 마찬가지이다.
int main() { Base* b = new Derived(); b->say(); delete b; return 0; }
World
- 상속의 생존주기 중 up-casting의 생존주기에서 상위 클래스의 소멸자만 호출됨을 확인할 수 있었다. 소멸자도 함수의 일종으로 virtual 기호를 사용하여 하위 클래스에서 재정의된 소멸자를 가리지 않을 수 있다.
#include <iostream> class Base { public: Base() { std::cout << "Base()" << std::endl; } virtual ~Base() { std::cout << "~Base()" << std::endl; } }; class Derived : public Base { private: int* value = new int; public: Derived() { std::cout << "Derived()" << std::endl; } ~Derived() { std::cout << "~Derived()" << std::endl; delete value; } }; int main() { Base* b = new Derived(); delete b; return 0; }
Base() Derived() ~Derived() ~Base()
반응형
'C++ > C to C++' 카테고리의 다른 글
[C to C++] 상속 - 순수 가상함수, 추상 클래스 (0) | 2019.02.03 |
---|---|
[C to C++] 상속 (0) | 2019.02.01 |
[C to C++] 템플릿 (0) | 2019.02.01 |
[C to C++] friend, 연산자 오버로딩 (0) | 2019.01.31 |
[C to C++] 함수 오버로딩 (0) | 2019.01.31 |
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- c++ 상속
- dokdo-project
- f320k
- c++ struct
- 객체지향
- C++
- Java
- inline class
- f320s
- vector
- CM11
- C++ 업캐스팅
- c++11
- OOP
- rule_of_three
- linaro
- Kotlin
- dokdo 4.0.3
- 포인터
- C
- d802
- CM10.2
- LG
- PipelineContext
- cyanogenmod
- dokdo project
- rule_of_five
- g2 korea
- nodeal
- G2
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
글 보관함