default 예약어
C++에서 생성자 오버로딩을 하면 컴파일러에 의한 디폴트 생성자는 생성되지 않습니다.
그래서 디폴트 생성자를 호출하려고 하면 컴파일 에러가 발생하는데요.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class TEST
{
public:
TEST(int);
void PrintNum() const;
private:
int num = 0;
};
TEST::TEST(int value):num(value)
{
cout << "TEST(int)" << endl;
}
void TEST::PrintNum() const
{
cout << "num:" << num << endl;
}
int main()
{
// TEST t; compile error! - 클래스의 기본 생성자가 없습니다.
TEST t(5);
t.PrintNum();
}
그렇기 때문에 생성자 오버로딩이 있고 디폴트 생성자도 필요한 경우라면, 명시적으로 디폴트 생성자를 작성해 줄 필요가 있습니다.
이때 선언과 정의를 분리시켜야 하는 코드이고 디폴트 생성자 정의부에 추가할 코드가 없다면 불필요하게 디폴트 생성자 정의부를 만들어야 합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class TEST
{
public:
TEST(); // 디폴트 생성자 선언
TEST(int);
/**
* 이하 생략
*/
};
TEST::TEST(){} // 디폴트 생성자 정의
TEST::TEST(int value):num(value)
{
cout << "TEST(int)" << endl;
}
이런 불필요한 선언과 정의를 나누는 행위를 없애기 위해 우리는 default 예약어를 사용할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
class TEST
{
public:
TEST() = default; // default 예약어를 통해 선언과 정의를 동시에 처리
TEST(int);
};
TEST::TEST(int value):num(value)
{
cout << "TEST(int)" << endl;
}
delete 예약어
디폴트 생성자를 생성하지 않기 위해 생성자 오버로딩을 사용하곤 합니다.
1
2
3
4
5
6
7
8
9
10
11
class TEST
{
public:
TEST(int);
}
int main()
{
// TEST t; compile error! - 클래스의 기본 생성자가 없습니다.
TEST t(5);
}
이렇게 처리할 경우
디폴트 생성자가 정말 필요가 없는 건지. 누락된 건지. 다른 곳에 정의가 된 건지 클래스만 보고선 알 방법이 없습니다
그렇기 때문에 확실하게 “디폴트 생성자는 삭제된 것이다”라고 명시하기 위해서 delete 예약어를 사용할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
class TEST
{
public:
TEST() = delete;
TEST(int);
}
int main()
{
TEST t; // compile error!! -> 기본 생성자를 참조할 수 없습니다. 삭제된 함수입니다.
}
만약에 delete 예약어를 사용하지 않을 경우 컴파일 에러 설명은 아래와 같이 노출되게 됩니다.
1
2
3
4
5
6
7
8
9
10
11
class TEST
{
public:
// TEST() = delete;
TEST(int);
}
int main()
{
TEST t; // compile error!!
}
응용
delete 예약어는 함수가 삭제된 함수임을 알려주는 예약어임을 위에서 확인했습니다.
이 기능을 이용해서 컴파일 에러를 발생시켜 휴먼 에러를 방지하는 기능으로도 사용이 가능한데요.
예시로 파라미터로 원하지 않는 자료형이 들어오는 것을 막을 수 있습니다.
1
2
void SetData(int value);
void SetData(double value) = delete;
위에처럼 코드를 구현하게 되면
SetData() 함수를 통해서 파라미터로 int 자료형은 가능하나 double 자료형을 전달하려고 하면 컴파일 에러가 발생하게 됩니다.
이처럼 컴파일 에러를 일부러 유발해 휴먼 에러를 방지하는 기능으로도 사용할 수 있습니다.