1. 생성자
멤버 변수 초기화
객체의 멤버 변수는 사용자나 프로그램이 일반적인 방법으로 초기화 할 수 없습니다.
private 멤버도 있으므로, 여기엔 직접 접근할 수 없기 때문입니다.
따라서, private 멤버 초기화를 위한 public 함수가 필요합니다.
이러한 초기화 함수는 객체가 생성된 후부터 사용되기 전까지 반드시 멤버의 초기화를 위해 호출되어야 합니다.
생성자(constructor)
c++에서는 객체의 생성과 동시에 멤버 변수를 초기화해주는 생성자 멤버 함수를 제공합니다.
생성자의 이름은 해당 클래스의 이름과 같습니다.
특별히, 객체를 초기화하는 방법이 여러 개 존재하는 경우, 오버로딩 규칙에 따라 여러개의 생성자를 가질 수 있습니다.
class Book{
private:
string title_;
int current_page_;
double percent_;
void set_percent();
public:
int total_page_;
Book(const string& title, int total_page){
title_ = title;
total_page_ = total_page;
current_page_ = 0;
set_percent();
}
};
void Book::set_percent() {
percent_ = (double) current_page_ / total_page_ * 100;
}
이렇게 생성자를 정의해 놓았다면,
생성자호출은 두가지 방법으로 할 수 있습니다.
Book book1("Linear Algebra", 689);
Book book1 = Book("Linear Algebra", 689);
2. 디폴트 생성자
초깃값을 명시하지 않으면, 컴파일러가 자동으로 0이나 NULL, 빈 문자열로 초기화합니다.
Book() {};
디폴트 생성자를 가지는 객체의 선언 3가지 방법
Book book1; // implicit
Book book1 = Book(); // explicit
Book *book1 = new Book; // implicit
3. 복사 생성자(Copy constructor)
얕은 복사와 깊은 복사
얕은복사는 대입연산자(=)를 통해 가능합니다.
Book book1("Linear Algebra", 689);
Book book2 = book1;
얕은 복사(shallow copy)란 값을 복사하는 것이 아닌, 값을 가리키는 포인터를 복사하는 것입니다.
하지만 문제점이 있는데,
예를 들면 객체의 멤버가 힙 메모리 공간을 참조할 경우에 이 방식이 문제가 생깁니다.
위와 같이 정의된 상황에서
book2 가 객체 수명이 끝날 때, 만약 book2에 멤버변수중 동적할당된 메모리(즉, 힙 영역사용)가 있다면, 그 멤버 변수는 소멸자에서 주소가 사라질 것입니다.
그렇다면 book1은 수명이 안 끝났음에도 불구하고, 그 멤버변수를 가리키고 있던 포인터가 사라짐으로써 원래 정보를 잃게 되는 문제점을 가지게 되는 것입니다.
깊은 복사(Deep copy)
class Book{
private:
...
string author;
public:
Book(const string& author_name) { // 디폴트 생성자
author = new string;
};
Book(const Book& origin) { // 깊은 복사 생성자의 선언
title_ = origin.title_;
total_page_ = origin.total_page_;
current_page_ = origin.current_page_;
percent_ = origin.percent_;
}
};
Book book1;
Book book2(book1);
깊은 복사로 위의 문제점을 해결할 수 있습니다.
4. 소멸자(Destructor)
객체의 수명이 끝나면 생성자의 반대역할을 수행할 멤버 함수가 필요합니다.
이 역할은 소멸자가 담당하며, 소멸자는 객체의 수명이 끝나면 컴파일러에 의해 자동으로 호출됩니다.
소멸자의 이름은 클래스의 이름과 같으며, 이름앞에 물결표시(tilde, ~)를 붙입니다.
~Book() {};
예를 들어 생성자에서 new 키워드를 통해 동적메모리를 할당했다면,
소멸자에서 메모리 누수(memory leak)를 방지하기 위해 delete 키워드를 통해 메모리를 반환해야 할 것입니다.
소멸자의 호출시기는 컴파일러가 알아서 처리하며,
객체가 선언된 메모리 영역별로 소멸자가 호출되는 시기는 다음과 같습니다.
객체가 호출된 메모리영역 | 소멸자 호출시기 |
---|---|
데이터 영역 | 해당 프로그램이 종료될 때 |
스택 영역 | 해당 객체가 정의된 블록을 벗어날 때 |
힙 영역 | delete를 사용하여 해당 객체 메모리를 반환할 때 |
임시 객체 | 임시 객체의 사용을 마쳤을 때 |
[출처 - TOPSCHOOL.com http://tcpschool.com/cpp]
'lang > C,C++' 카테고리의 다른 글
[Class와 OOP] 4. OOP 캡슐화, 프렌드(freind), static, const 멤버 변수, 함수 (1013) | 2019.10.09 |
---|---|
[Class] 3. Class - 연산자오버로딩 (953) | 2019.10.09 |
[Class] 1. Class - 객체지향 프로그래밍 OOP 4가지 특징 (1313) | 2019.10.09 |
[STL] erase (0) | 2019.09.19 |
C++ String (#include <string>) (0) | 2019.09.03 |
댓글