이번에는 클래스의 생성자와 소멸자에 대해 알아보겠습니다.
생성자는 객체가 선언될 때 자동으로 호출이 되는 특수한 멤버 함수입니다.
보통 생성자를 이용해서 객체가 선언될 때 객체를 초기화를 할 수 있습니다.
클래스 이름과 동일한 함수명을 가지고 있습니다.
생성자는 특수한 함수답게 반환값이 없습니다. 반환값이 없다 보니 자료형을 붙이지 않고 정의합니다.
예제를 통해서 알아보겠습니다.
#include <iostream>
using namespace std;
class Student {
public:
Student() //생성자
{
cout << "객체 생성 \n";
}
};
int main()
{
Student str;
return 0;
}
기본적으로 생성자는 객체가 생성되면 자동으로 호출되는 결과를 볼 수 있습니다.
main함수에서 아무 메서드도 호출하지 않았지만 자동으로 생성자가 호출되어 내부의 명령이 실행됩니다.
생성자의 다른 사용법도 알아보겠습니다.만약 클래스 내부에 변수를 초기화하지 않고 호출하면 어떤 결과가 나오는지 알아보겠습니다.
#include <iostream>
using namespace std;
class Student {
private:
int age;
public:
void show() {
cout << age << '\n';
}
};
int main()
{
Student str;
str.show();
return 0;
}
초기화되지 않은 변수를 사용하여 쓰레기 값이 출력됩니다.
private으로 접근 지정자를 선언해서 외부에서 초기화도 불가능합니다.
한두개의 변수야 직접 초기화도 가능하지만 양이 많아지게 되면 하나하나 초기화하려면 굉장히 번거로운 작업이 될 수 있습니다.
이때 생성자를 이용하여 한번에 0으로 초기화가 가능합니다.
다시 예제를 수정해보겠습니다.
#include <iostream>
using namespace std;
class Student {
private:
int age;
public:
void show() {
cout << age << '\n';
}
};
int main()
{
Student str{};
str.show();
return 0;
}
객체를 생성할때 빈 {}중괄호를 붙여주면 초기화되지않은 변수들이 모두 0으로 (문자는 \0) 초기화됩니다.
단 이때 클래스 내부에 생성자를 정의하지 않은 상태이거나(기본 생성자) 매개변수를 갖지 않은 기본 생성자를 직접 정의해야 합니다.
{}는 균일한 초기화(Uniform initialization)라고 해서 ()나 =와는 조금 다른 개념입니다.(C++ 11부터 추가)
빈 중괄호는 기본 초기화로 변수를 모두 0으로 초기화해줍니다.
생성자는 매개변수를 가질 수 있습니다.
예제를 통해서 생성자에 매개변수를 추가해보겠습니다.
#include <iostream>
#include <string>
using namespace std;
class Student {
private:
string name;
int age;
public:
Student(string name,int age) {
this->name = name;
this->age = age;
}
void show() {
cout << "이름 : " << name << '\n';
cout << "나이 : " << age << '\n';
}
};
int main()
{
Student str("홍길동",16);
str.show();
return 0;
}
매개변수를 가지는 생성자를 만들게 되면 객체를 선언할 때 인자를 넘겨주지 않으면 에러가 발생합니다.
생성자에서 this는 this 포인터로 객체 자신을 가리키는 포인터입니다.
this와 ->(포인터 연산자)를 이용해서 자신의 클래스 내부의 변수 또는 함수를 사용할 수 있습니다. 위의 예제처럼 매개변수의 이름이 클래스 내부 변수 이름과 같을 때 구분용으로 많이 사용하기도 합니다.
다음으로 생성자는 여러 개 선언이 가능합니다.
위의 예제를 예로 들었을 때 학생의 이름은 알지만 나이를 모를 수도 있고 일단 객체만 생성하고 싶을 수도 있습니다.
다시 예제를 수정해보겠습니다.
#include <iostream>
#include <string>
using namespace std;
class Student {
private:
string name;
int age;
public:
Student() {
cout << "객체 생성 \n\n";
}
Student(string name) {
this->name = name;
this->age = 0;
show();
}
Student(string name,int age) {
this->name = name;
this->age = age;
show();
}
void show() {
cout << "이름 : " << name << '\n';
cout << "나이 : " << age << '\n';
}
};
int main()
{
Student str1;
Student str2{"홍길동"};
Student str3("홍길동",16);
return 0;
}
각각 객체를 생성할 때 원하는 생성자의 매개변수에 맞게 인자를 넘기면 해당 생성자가 호출됩니다.
여기서 {}(중괄호)로 매개변수를 가진 생성자를 초기화할 때 주의해야할 점이 있습니다.
균일한 초기화는 형 변환을 허용하지 않습니다.
예를 들어 int형의 매개변수를 가지는 생성자가 있는 경우
class Student {
private:
int age;
public:
Student(int age) {
this->age = age;
}
};
()괄호로 초기화할 때는 실수형을 넘겨도 자료 손실이 있다는 주의 메시지만 출력되고 정상적으로 실행되고
내림 후 변수에 저장됩니다.
Student str1( 3.5 );
하지만 {}중괄호는 에러가 발생합니다.
Student str2{ 3.5 };
균일한 초기화는 형 변환을 허락하지 않기 때문입니다.
이제 소멸자에 대해 알아보겠습니다.
소멸자는 객체가 소멸할 때 자동으로 호출되는 함수입니다.
소멸자도 클래스명과 같은 이름입니다 대신 생성자와 구분하기 위해 이름 앞에 ~가 붙습니다.
소멸자도 기본적으로 호출되기 때문에 따로 선언할 필요는 없습니다.
#include <iostream>
#include <string>
using namespace std;
class Student {
public:
~Student() {
cout << "객체 소멸 \n";
}
};
int main()
{
Student *str1 = new Student;
delete str1;
return 0;
}
여기서 new는 동적 할당을 위한 연산자로 나중에 따로 하겠습니다.
new로 생성된 객체 포인터를 delete로 소멸시키자 자동으로 소멸자가 호출되어 메시지가 출력됩니다.
'공부 자료실 > C++' 카테고리의 다른 글
C++ - 동적 메모리 할당 (0) | 2020.08.25 |
---|---|
C++ - 클래스(class) 상속 (0) | 2020.08.21 |
C++ - string 클래스 (0) | 2020.08.18 |
C++ - 클래스(Class)의 구조와 접근 지정자 (0) | 2020.08.17 |
C++ - 네임스페이스(namespace) (0) | 2020.08.13 |
댓글