상속이란? - 기반클래스로부터 다른 클래스를 파생하는 법 protected란? 가상함수 (virtual function)

Slides:



Advertisements
Similar presentations
윤성우 저 열혈강의 C++ 프로그래밍 개정판 Chapter 01. C 언어 기반의 C++ 1.
Advertisements

Kim Yeon Hee 8장. 상속과 다형성 Kim Yeon Hee.
3. C++와 객체지향 C++ 코딩 방법 객체 단위로 2 개의 파일 인터페이스 파일 구현파일
명품 C++ 프로그래밍 3장. 클래스와 객체.
명품 C++ 8장 상속.
Power C++ 제6장 포인터와 문자열.
C++ Espresso 제1장 기초 사항.
C++ Espresso 제2장 제어문과 함수.
강좌명 : C++프로그래밍 (C++ Programming)
Chapter 6 구조체.
C++ 프로그래밍 년 2학기 전자정보공학대학 컴퓨터공학부.
제6장 객체배열과 벡터 객체 배열을 이해한다. 벡터(vector) 클래스를 사용할 수 있다.
C++ Exspresso 제5장 클래스의 기초.
2주 실습강의 Java의 기본문법(1) 인공지능연구실.
8. 객체와 클래스 (기본).
명품 JAVA Programming.
제12장 다형성과 가상함수 다형성의 개념을 이해한다. 상향 형변환의 개념을 이해한다. 가상 함수의 개념을 이해한다.
C++ Espresso 제9장 다형성.
10장 객체-지향 프로그래밍 II ©창병모.
명품 C++ 8장 상속.
윤성우의 열혈 C 프로그래밍 윤성우 저 열혈강의 C 프로그래밍 개정판 Chapter 14. 포인터와 함수에 대한 이해.
C++ Espresso 제6장 생성자와 소멸자.
6. 기본 클래스 프로그래밍 6 컴퓨터공학과 신동일.
윤성우의 열혈 C++ 프로그래밍 윤성우 저 열혈강의 C++ 프로그래밍 개정판 Chapter 03. 클래스의 기본.
명품 Java Programming.
MFC Application Frameworks (AFX)
7장 클래스.
다중 상속 - 가상 상속 추상 자료형 순수 가상함수
명품 C++ 7장 프렌드와 연산자 중복.
18장. 헤더 파일과 구현 파일 01_ 헤더 파일과 구현 파일의 사용.
14장. 함수 1 01_ 함수의 기본 02_ 인자의 전달.
C ++ 프로그래밍 시작.
정적 멤버 변수/정적 멤버 함수 - friend 함수/클래스 template
C++ Programming: chapter 7 – inheritence
윤성우의 열혈 C++ 프로그래밍 윤성우 저 열혈강의 C++ 프로그래밍 개정판 Chapter 08. 상속과 다형성.
C++ 개요 객체지향 윈도우즈 프로그래밍 한국성서대학교 유일선
배열이란? 배열의 선언? - 배열과 포인터의 관계? 문자열이란? 문자배열 연결 리스트
스택(Stack) 김진수
17장. 문자열 01_ 문자열 사용의 기본 02_ 문자열의 사용.
명품 C++ 프로그래밍 1장. C++ 시작.
C++ 프로그래밍 년 2학기 전자정보공학대학 컴퓨터공학부.
Chapter 3 클래스. 최호성.
제5장 생성자와 접근제어 객체 지향 기법을 이해한다. 클래스를 작성할 수 있다. 클래스에서 객체를 생성할 수 있다.
C++ Espresso 제8장 상속.
가상함수와 추상 클래스.
Chapter 1 C와는 다른 C++. 최호성.
C# 09장. 상속성.
제2장 제어구조와 배열 if-else 문에 대하여 학습한다. 중첩 if-else 문에 대하여 학습한다.
제 12장. 사용자 정의형으로서의 클래스 학기 프로그래밍언어및실습 (C++).
4. 고급변수 사용 : 포인터와 관련하여 메모리 바라보기
프로그래머를 위한 첫걸음 JDBC Lecture 001 BY MINIO
멤버 함수인 operator+()가 실행, 또는 전역 함수인 operator+()가 실행 Point p3 = p1+p2; 에서
멤버함수 중첩( 복사 생성자 ) - 연사자 중첩 - 동적 메모리를 가지는 클래스를 지원 하도록 멤버 함수 작성
제8장 포인터와 동적객체 생성 포인터의 개념을 이해한다. 포인터와 관련된 연산을 이해한다.
A Basic of C++.
5. 논리적 자료표현 : 구조체.
[ 단원 06 ] 상속과 다형성.
조 병 규 Software Quality Lab. 한 국 교 통 대 학 교
제 11장. 템플릿과 STL 학기 프로그래밍언어및실습 (C++).
3장,4장 발표 서정우.
03. 메모리 관리 C++ 프로그램에서 다룰 수 있는 메모리의 종류
포인터와 배열 조 병 규 한 국 교 통 대 학 교 SQ Lab..
6장 클래스(상속).
제 8장. 클래스의 활용 학기 프로그래밍언어및실습 (C++).
자료구조 세미나 발표 주제: 자료구조 기초 - 1회 차: 자료구조의 정의, 기초 지식 (함수, 포인터, 레퍼런스)
캡슐화 (Encapsulation) 두원공과대학 소프트웨어개발과 이 원 주.
실습과제 1번 /* 1. 멤버 변수로 반경 radius를 갖고, 그 값을 모니터에 출력하는
C# 09장. 클래스와 객체.
C++ 언어의 특징
발 표 자 : 7조 손 창 국 윤 오 성, 박 진 완 객체 지향 프로그래밍 C++
Presentation transcript:

상속이란? - 기반클래스로부터 다른 클래스를 파생하는 법 protected란? 가상함수 (virtual function)

상속이란? Animal Mammal Reptile Horse Dog 상속 파생 각 개념들간의 계층 구조에서 상위 개념(표유류)의 일반적인 특성을 하위 개념(개)이 이어 받는 것 계층 구조는 “한 종류”라는 식으로 표현 : 도요타는 차의 한 종류 파생 상위 클래스(기반/기본 클래스, 부모 클래스, base class)에서 새로운 특성을 추가하여 새로운 클래스(파생 클래스, derived class, child class)를 만드는 것 Animal Mammal Reptile Horse Dog

파생 구문 파생 클래스가 어디로부터 파생하였는지를 표시 class 파생클래스명 : 파생의형 기반클래스명 기반 클래스는 이전에 선언되어 있어야 함 파생 클래스는 기반 클래스의 생성자, 소멸자, friend 함수를 제외한 모든 것을 상속 class 파생클래스명 : 파생의형 기반클래스명 class Dog : public Mammal

#include <iostream> using namespace std; enum BREED { GOLDEN, CAIRN, DANDIE}; class Mammal { public: Mammal(); ~Mammal(); int GetAge() const; void SetAge(int); int GetWeight() const; void SetWeight(); void Speak() const; void Sleep() const; protected: int itsAge; int itsWeight; }; list 12.1

class Dog : public Mammal { public: Dog(); ~Dog(); BREED GetBreed() const; void SetBreed(BREED); WagTail(); BegForFood(); protected: BREED itsBreed; };

전용(private) vs. 보호(protected) (기반 클래스) public 파생된 클래스 : 접근 가능 기반 & 파생 클래스 외부 : 접근 가능 (기반 클래스) private 파생된 클래스 : 접근 불능 기반 & 파생 클래스 외부 : 접근 불능 (기반 클래스) protected

#include <iostream> using std::cout; enum BREED { GOLDEN, CAIRN, DANDIE}; class Mammal { public: Mammal():itsAge(2), itsWeight(5){} ~Mammal(){} int GetAge() const { return itsAge; } void SetAge(int age) { itsAge = age; } int GetWeight() const { return itsWeight; } void SetWeight(int weight) { itsWeight = weight; } void Speak()const { cout << "Mammal sound!\n"; } void Sleep()const { cout << "shhh. I'm sleeping.\n"; } protected: int itsAge; int itsWeight; }; list 12.2

class Dog : public Mammal { public: Dog():itsBreed(GOLDEN){} ~Dog(){} BREED GetBreed() const { return itsBreed; } void SetBreed(BREED breed) { itsBreed = breed; } void WagTail() const { cout << "Tail wagging...\n"; } void BegForFood() const { cout << "Begging for food...\n"; } private: BREED itsBreed; }; int main() Dog fido; fido.Speak(); fido.WagTail(); cout << "Fido is " << fido.GetAge() << " years old\n"; return 0; }

class Parent { public: int b; void f(){a=1;} private: int a; }; class Child : public Parent void g(){ a=1; // (1) b=1; // (2) f(); // (3) } int c; int main() Child Tom; Tom.b = 3; // (4) Tom.a = 4; // (5) Tom.c = 5; // (6)

class Parent { public: int b; void f(){a=1;} protected: int a; }; class Child : public Parent void g(){ a=1; // (1) b=1; // (2) f(); // (3) } private: int c; int main() Child Tom; Tom.b = 3; // (4) Tom.a = 4; // (5) Tom.c = 5; // (6)

상속에서의 생성자와 소멸자 파생 클래스의 객체 생성 시 : 생성자 파생 클래스의 객체 소멸 시 : 소멸자 기반 클래스의 생성자 호출 파생 클래스의 생성자 호출 파생 클래스의 객체 소멸 시 : 소멸자 파생 클래스의 소멸자 호출 기반 클래스의 소멸자 호출 각각의 부분을 생성하고 소멸 시킴 기반 클래스의 생성자에게 인자 전달 기반 클래스의 생성자가 중첩되어 있는 경우 파생 클래스의 생성자 함수에서 기반 클래스의 생성자 함수 호출 기본 생성자 이외의 기반 클래스 생성자 실행 가능

#include <iostream> using namespace std; enum BREED { GOLDEN, CAIRN, DANDIE}; class Mammal { public: Mammal(); Mammal(int age); ~Mammal(); int GetAge() const { return itsAge; } void SetAge(int age) { itsAge = age; } int GetWeight() const { return itsWeight; } void SetWeight(int weight) { itsWeight = weight; } void Speak() const { cout << "Mammal sound!\n"; } void Sleep() const { cout << "shhh. I'm sleeping.\n"; } protected: int itsAge; int itsWeight; }; list 12.4

class Dog : public Mammal { public: Dog(); Dog(int age); Dog(int age, int weight); Dog(int age, BREED breed); Dog(int age, int weight, BREED breed); ~Dog(); BREED GetBreed() const { return itsBreed; } void SetBreed(BREED breed) { itsBreed = breed; } void WagTail() const { cout << "Tail wagging...\n"; } void BegForFood() const { cout << "Begging for food...\n"; } private: BREED itsBreed; };

Mammal::Mammal(): itsAge(1), itsWeight(5) { cout << "Mammal constructor...\n"; } Mammal::Mammal(int age): itsAge(age), itsWeight(5) cout << "Mammal(int) constructor...\n"; Mammal::~Mammal() cout << "Mammal destructor...\n";

(X) Dog::Dog(): Mammal(), itsBreed(GOLDEN) { cout << "Dog constructor...\n"; } Dog::Dog(int age): Mammal(age), itsBreed(GOLDEN) cout << "Dog(int) constructor...\n"; Dog::Dog(int age, int weight): Mammal(age), itsBreed(GOLDEN) itsWeight = weight; cout << "Dog(int, int) constructor...\n"; Dog::Dog(int age, int weight, BREED breed): Mammal(age), itsBreed(breed) cout << "Dog(int, int, BREED) constructor...\n"; ,itsWeight(weight) (X)

Dog::Dog(int age, BREED breed): Mammal(age), itsBreed(breed) { cout << "Dog(int, BREED) constructor...\n"; } Dog::~Dog() cout << "Dog destructor...\n"; int main() Dog fido; Dog rover(5); Dog buster(6,8); Dog yorkie (3,GOLDEN); Dog dobbie (4,20,DOBERMAN); fido.Speak(); rover.WagTail(); cout << "Yorkie is " << yorkie.GetAge() << " years old\n"; cout << "Dobbie weighs "; cout << dobbie.GetWeight() << " pounds\n"; return 0;

함수 재정의/재생 (Overriding Function) 파생 클래스에서 기반 클래스의 함수 구현부를 새로이 만드는 것 함수의 반환 형, 원형부가 일치해야 함 함수 반환형 매개 변수의 목록 상수형 함수 표시 기반 클래스의 하나의 함수를 재정의하면 동일한 이름을 가진 모든 기반 클래스의 함수(중첩된 모든 기반 클래스의 함수)를 은폐 시키게 됨 기반 클래스의 함수가 재정의 되었더라도 함수의 이름을 완전하게 다 써주면 호출할 수 있음 파생클래스의객체명.기반클래스명::함수명( ) 중첩, 다중정의 (Overloading) vs. 재정의, 재생(Overriding)

#include <iostream> using namespace std; class Mammal { public: void Move() const { cout << "Mammal move one step\n"; } void Move(int distance) const cout << "Mammal move " << distance; cout << " steps.\n"; } protected: int itsAge; int itsWeight; }; list 12.7

class Dog : public Mammal { public: void Move() const; }; void Dog::Move() const cout << "In dog move...\n"; Mammal::Move(3); } int main() Mammal bigAnimal; Dog fido; bigAnimal.Move(); bigAnimal.Move(2); fido.Move( ); fido.Move(6); fido.Mammal::Move(6); fido.Mammal::Move( ); return 0;

가상 메소드/함수 (Virtual Method) 기반클래스를 가리키는 포인터에 파생 클래스의 포인터를 대입하는 다형성(polymorphism) 지원 Dog는 Mammal의 한 종류이므로 가능 반대는 불가능 pMammal 포인터를 이용해 Mammal의 멤버 함수 호출 가능 Dog의 멤버 함수를 호출하려면? Mammal *pMammal = new Dog 가상 함수 기반 클래스의 함수를 가상함수로 만듦 virtual 반환형 함수명( 매개변수 리스트 )

#include <iostream> using std::cout; class Mammal { public: Mammal():itsAge(1) { cout << "Mammal constructor...\n"; } virtual ~Mammal() { cout << "Mammal destructor...\n"; } void Move() const { cout << "Mammal move one step\n"; } virtual void Speak() const { cout << "Mammal speak!\n"; } protected: int itsAge; }; list 12.8

class Dog : public Mammal { public: Dog() { cout << "Dog Constructor...\n"; } virtual ~Dog() { cout << "Dog destructor...\n"; } void WagTail() { cout << "Wagging Tail...\n"; } void Speak() const { cout << "Woof!\n"; } void Move() const { cout << "Dog moves 5 steps...\n"; } }; int main() Mammal *pDog = new Dog; pDog->Move(); pDog->Speak(); pDog->WagTail(); Dog *ptemp = new Mammal; return 0; }

#include <iostream> using namespace std; class Mammal { public: Mammal():itsAge(1) { } virtual ~Mammal() { } virtual void Speak() const { cout << "Mammal speak!\n"; } protected: int itsAge; }; list 12.9

class Dog : public Mammal { public: void Speak() const { cout << "Woof!\n"; } }; class Cat : public Mammal void Speak() const { cout << "Meow!\n"; } class Horse : public Mammal void Speak() const { cout << "Winnie!\n"; } class Pig : public Mammal void Speak() const { cout << "Oink!\n"; }

int main() { Mammal* theArray[5]; Mammal* ptr; int choice, i; for ( i = 0 ; i<5 ; i++ ) cout << "(1)dog (2)cat (3)horse (4)pig: "; cin >> choice; switch (choice) case 1: ptr = new Dog; break; case 2: ptr = new Cat; case 3: ptr = new Horse; case 4: ptr = new Pig; default: ptr = new Mammal; } theArray[i] = ptr; for ( i=0 ; i<5 ; i++ ) theArray[i]->Speak(); return 0;

다형성(polymorphism) 하나의 이름을 두 개 또는 그 이상의 관련된 목적에 사용할 수 있도록 하는 성질 함수 중첩 기반 클래스의 포인터에 파생 클래스의 포인터 대입 가능 기본 클래스에서 멤버 함수를 가상으로 만들었을 경우 파생 클래스에서도 가상으로 하여야 하는가? 역시 가상으로 되어 있지만 하는 것이 이해하기 좋음 하나의 이름을 두 개 또는 그 이상의 관련된 목적에 사용할 수 있도록 하는 성질

가상함수의 동작 원리 동적 바인딩(dynamic binding) 실행 바인딩(run-time binding) 가상함수를 위해서는 동적 바인딩 필요 가상함수가 존재하는 class의 객체가 만들어지면 객체는 그 함수를 추적해야 함 컴파일러는 가상함수테이블(virtual function table, v-table)을 만듦 각각의 파생 객체는 가상 테이블의 포인터 (vptr)를 유지하여야 함 동적 바인딩(dynamic binding) 실행 바인딩(run-time binding) 정적(static binding) 컴파일 바인딩(compile binding)

가상함수의 동작원리 (cont.) VPTR &Move( ) &Speak( ) Mammal VPTR Mammal Mammal의 v-table Dog의 v-table VPTR &Move( ) &Speak( ) Mammal VPTR Mammal &Mammal:Move( ) &Dog:Speak( ) Dog Mammal을 가리키는 포인터가 사용되더라도 vptr은 객체의 실제형에 대한 함수를 가리키고 있음

기타 포인터와 참조자를 사용하는 경우 이러한 동작 가능 객체를 값으로 전달 시 가상함수 호출 되게 할 수 없음

#include <iostream> class Mammal { public: Mammal():itsAge(1) { } virtual ~Mammal() { } virtual void Speak() const { std::cout << "Mammal speak!\n"; } protected: int itsAge; }; class Dog : public Mammal void Speak() const { std::cout << "Woof!\n"; } class Cat : public Mammal void Speak() const { std::cout << "Meow!\n"; } list 12.10

void ValueFunction (Mammal MammalValue) { MammalValue.Speak(); } void PtrFunction (Mammal * pMammal) pMammal->Speak(); void RefFunction (Mammal & rMammal) rMammal.Speak();

int main() { Mammal* ptr=0; int choice; ptr = new Cat; PtrFunction(ptr); RefFunction(*ptr); ValueFunction(*ptr); delete ptr; ptr = new Dog; return 0; }

가상 소멸자(virtual destructor) 기본클래스에서 가상인 함수가 있으면 그 소멸자도 가상이어야 한다 기본클래스의 소멸자가 가상이면 파생클래스의 소멸자가 호출

가상 복사 생성자 (Virtual Copy Constructor) 생성자는 가상이 될 수 없으므로 가상 복사 생성자는 없음 실질적인 복사를 수행한 후 복사된 객체에 대한 포인터를 반환 기반 클래스에서 Clone( ) 메소드를 가상으로 만듦

#include <iostream> using namespace std; class Mammal { public: Mammal():itsAge(1) { cout << "Mammal constructor...\n"; } virtual ~Mammal() { cout << "Mammal destructor...\n"; } Mammal (const Mammal & rhs); virtual void Speak() const { cout << "Mammal speak!\n"; } virtual Mammal* Clone() { return new Mammal(*this); } int GetAge() const { return itsAge; } protected: int itsAge; }; Mammal::Mammal (const Mammal & rhs): itsAge(rhs.GetAge()) cout << "Mammal Copy Constructor...\n"; } list 12.11

class Dog : public Mammal { public: Dog() { cout << "Dog constructor...\n"; } virtual ~Dog() { cout << "Dog destructor...\n"; } Dog (const Dog & rhs); void Speak()const { cout << "Woof!\n"; } virtual Mammal* Clone() { return new Dog(*this); } }; Dog::Dog(const Dog & rhs): Mammal(rhs) cout << "Dog copy constructor...\n"; }

class Cat : public Mammal { public: Cat() { cout << "Cat constructor...\n"; } ~Cat() { cout << "Cat destructor...\n"; } Cat (const Cat &); void Speak()const { cout << "Meow!\n"; } virtual Mammal* Clone() { return new Cat(*this); } }; Cat::Cat(const Cat & rhs): Mammal(rhs) cout << "Cat copy constructor...\n"; }

enum ANIMALS { MAMMAL, DOG, CAT}; const int NumAnimalTypes = 3; int main() { Mammal *theArray[NumAnimalTypes]; Mammal* ptr; int choice, i; for ( i = 0; i<NumAnimalTypes; i++) cout << "(1)dog (2)cat (3)Mammal: "; cin >> choice; switch (choice) case DOG: ptr = new Dog; break; case CAT: ptr = new Cat; default: ptr = new Mammal; } theArray[i] = ptr;

Mammal *OtherArray[NumAnimalTypes]; for (i=0;i<NumAnimalTypes;i++) { theArray[i]->Speak(); OtherArray[i] = theArray[i]->Clone(); } OtherArray[i]->Speak(); return 0;