728x90
반응형
1. 상속에서의 생성자 소멸자
#include <iostream>
using namespace std;
class Base {
int data;
public:
Base() { cout << "Base()" << endl; }
Base(int a) { cout << "Base(int)" << endl; }
~Base() { cout << "~Base()" << endl; }
};
class Derived : public Base {
public:
Derived() { cout << "Derived()" << endl; }
Derived(int a) { cout << "Derived(int)" << endl; }
~Derived() { cout << "~Derived()" << endl; }
};
int main() {
Derived d;
}
실행결과
Base()
Derived()
~Derived()
~Base()
① 파생 클래스의 객체 생성시 생성자/소멸자 호출순서
=> 기반 클래스 생성자 / 파생 클래스 생성자
=> 파생 클래스 소멸자 / 기반 클래스 소멸자
int main() {
Derived d(5);
}
실행결과
Base()
Derived(int)
~Derived()
~Base()
② 파생 클래스의 객체 생성시 인자가 있을 때
=> 기반 클래스 생성자는 디폴트 생성자 호출
=> 기반 클래스의 다른 생성자를 호출하려면 명시적으로 호출해야 한다.
Derived(int a) : Base(a) { cout << "Derived(int)" < endl; }
2. 생성자/소멸자 호출의 정확한 원리
#include <iostream>
using namespace std;
class Base {
int data;
public:
Base() { cout << "Base()" << endl; }
Base(int a) { cout << "Base(int)" << endl; }
~Base() { cout << "~Base()" << endl; }
};
class Derived : public Base {
public:
Derived() { cout << "Derived()" << endl; }
Derived(int a) : Base(a) { cout << "Derived(int)" << endl; }
~Derived() { cout << "~Derived()" << endl; }
};
int main() {
Derived d(5);
}
① 정확한 원리
=> 파생 클래스의 생성자에서 기반 클래스의 생성자를 호출하는 코드를 컴파일러가 생성해 주는 것
#include <iostream>
using namespace std;
class Base {
int data;
public:
Base() { cout << "Base()" << endl; }
Base(int a) { cout << "Base(int)" << endl; }
~Base() { cout << "~Base()" << endl; }
};
class Derived : public Base {
public:
Derived() : Base() { cout << "Derived()" << endl; }
Derived(int a) : Base() { cout << "Derived(int)" << endl; }
~Derived() { cout << "~Derived()" << endl; ~Base(); }
};
int main() {
Derived d;
}
3. 상속에서의 생성자/소멸자 예제
// 1
class Animal {
public:
Animal() {}
};
// 2
class Animal {
private:
Animal() {}
};
// 3
class Animal {
protected:
Animal() {}
};
class Dog : public Animal {
public:
Dog() : Animal() {}
};
int main() {
Animal a;
Dog d;
}
위의 코드에서 1 , 2 , 3번 코드 중 error가 나는 코드는 무엇일까?
=> 2, 3
① protected 생성자
=> 자기 자신은 객체를 만들 수 없지만 (추상적인 존재)
=> 파생 클래스의 객체는 만들 수 있게 하는 의미
4. 주의사항
#include <string>
class Person {
std::string name;
int age;
public:
Person( std::string n, int a ) : name(n), age(a) {}
};
class Student : public Person {
int id;
public:
Student() : id(0) {}
Student(int i) : id(i) {}
};
int main() {
Student s1;
Student s2(100);
}
위의 코드는 얼핏봐선 문제 없어서 보이지만 컴파일 시 에러가 난다.
위의 2번에서 설명했던 것처럼 상속을 받으면 컴파일러가 Student : Person() 과 같이 디폴트 생성자를 붙여주는데
디폴트 생성자가 없기 때문에 발생한 에러이다.
#include <string>
class Person {
std::string name;
int age;
public:
Person( std::string n, int a ) : name(n), age(a) {}
};
class Student : public Person {
int id;
public:
Student() : Person("unknown", 0), id(0) {}
Student(std::string n, int a, int i)
: Person(n, a), id(i) {}
};
int main() {
Student s1;
Student s2("kim", 20, 100);
}
① 기반 클래스에 디폴트 생성자가 없다면
=> 파생 클래스를 만들 때 반드시 기반 클래스의 생성자를 명시적으로 호출해야 한다.
=> 기반 클래스의 생성자를 명시적으로 호출하는 코드는 구현부(소스파일)에 작성한다.
728x90
반응형
'프로그래밍 > C++' 카테고리의 다른 글
[C++] 가상 함수 (virtual function) (2) | 2019.11.26 |
---|---|
[C++] upcasting (0) | 2019.11.26 |
[C++] 상속과 접근 지정자 (access specifiers) (1) | 2019.11.25 |
[C++] 상속 (0) | 2019.11.24 |
[C++] this 포인터 (0) | 2019.11.24 |