■ C++ 생성자, 소멸자
ㆍ 생성자
- 클래스의 이름과 함수의 이름이 동일
- 반환형이 선언되어 있지 않다
- 객체 생성 시 딱 한 번 호출된다
- 생성자도 함수의 일종이니 '오버로딩'이 가능
- 생성자도 함수의 일종이니 '디폴트 값'을 설정할 수 있다.
ex> 오버로딩 사용
class SimpleClass
{
private:
int num;
public:
SimpleClass(){
num=1;
}
SimpleClass(int n){
num=n;
}
};
ex> 멤버 이니셜라이저 사용
class SimpleClass
{
private:
int num;
public:
SimpleClass() : num(0)
{ }
SimpleClass(int n) : num(n)
{ }
};
* 이니셜라이저를 이용하면 선언과 동시에 초기화가 이뤄지는 형태로 바이너리 코드가 생성되기 때문에, const 멤버변수를 초기화할 수 있고, 성능에 약간의 이점이 있다.
ㆍ 소멸자
- 반환형이 선언되어 있지 않다
- 매게변수는 void형으로 선언되어야 하기 때문에, '오버로딩' 사용과 '디폴트 값' 설정이 불가능하다
- 객체 소멸시 딱 한 번 호출된다
ex>
class Person
{
private:
char* name;
int age;
public:
Person(){
name = NULL;
age=0;
}
Person(char* myname, int myage){
int len = strlen(myname)+1;
name = new char[len];
strcpy(name,myname);
age=myage;
}
~Person(){
delete []name;
}
};
ㆍ 복사 생성자
- "Person p1=p2"는 "Person p1(p2)"로 묵시적 변환이 되어 객체가 생성된다.
- 기본적으로 "디폴트 복사 생성자"가 있기 때문에 정의할 필요 없다.
=> 디폴트 복사 생성자는 멤버 대 멤버의 복사(얕은 복사)를 하기 때문에, 동적 할당 시 에러가 발생한다. 이를 해결하기 위해 깊은 복사를 하는 복사 생성자를 정의해야 한다.
ex> 깊은 복사
class Person
{
private:
char* name;
int age;
public:
Person(){
name = NULL;
age=0;
}
Person(char* myname, int myage){
int len = strlen(myname)+1;
name = new char[len];
strcpy(name,myname);
age=myage;
}
Person(const Person& copy) : age(copy.age) {
name = new char[strlen(copy.name)+1];
strcpy(name,myname);
}
~Person(){
delete []name;
}
};
* 복사 생성자의 매개변수는 반드시 참조형이어야 한다. 그렇지 않으면 무한 루프에 빠진다.
=> Person(Person copy)인 경우, 복사 생성자가 호출되면 Person copy=copy2 -> Person copy(copy2)가 되므로 다시 copy를 초기화하기 위해 복사 생성자가 생성된다. 이 경우가 계속 반복되어 무한 루프가 생성된다.
'Coding > C & C++' 카테고리의 다른 글
C++ 가상 함수 (0) | 2020.02.25 |
---|---|
C++ 상속 정리 (0) | 2020.02.24 |
C/C++ 파일 분할과 헤더 파일의 디자인 (0) | 2020.02.18 |
C/C++ 구조체(struct, class) (0) | 2020.02.18 |
C/C++ 함수 오버로딩 vs 함수 오버라이딩 (0) | 2020.01.31 |