C++ 프로그래밍을 하다 보면 "생성자를 직접 정의했을 때에도 컴파일러가 여전히 기본 생성자(default constructor)를 자동으로 만들어 주는지" 궁금해지는 순간이 있습니다. 이 글에서는 그 동작 원리를 간단한 코드 예제와 함께 살펴보겠습니다.
핵심 규칙
C++ 컴파일러의 기본 동작은 다음 두 가지로 정리할 수 있습니다.
- 생성자가 하나도 정의되어 있지 않은 경우: 컴파일러가 암시적 기본 생성자(implicit default constructor)를 자동으로 생성합니다.
- 사용자가 생성자를 하나라도 정의한 경우: 컴파일러는 더 이상 기본 생성자를 자동으로 만들어 주지 않으며, 오직 사용자가 정의한 생성자만 사용합니다.
즉, 매개변수가 있는 생성자만 정의했다면 인수 없이 객체를 생성할 수 없게 되므로, 필요하다면 기본 생성자를 직접 정의해 주어야 합니다.
예제 1: 생성자를 정의하지 않은 경우
#include<iostream>
using namespace std;
class myInteger {
private:
int value;
// 클래스 내 다른 멤버 함수들
};
int main(){
myInteger I1; // 인수 없이 객체 생성
getchar();
return 0;
}
출력 결과:
컴파일 성공
myInteger 클래스에는 어떤 생성자도 정의되어 있지 않습니다. 이 경우 컴파일러가 암시적 기본 생성자를 자동으로 생성해 주기 때문에 main() 함수에서 인수 없이 객체를 선언해도 아무 문제없이 컴파일됩니다.
예제 2: 매개변수가 있는 생성자를 정의한 경우
#include<iostream>
using namespace std;
class myInteger {
private:
int value;
public:
myInteger(int v) { // 사용자 정의 생성자
value = v;
}
// 클래스 내 다른 멤버 함수들
};
int main(){
myInteger I1; // 인수 없이 객체 생성 시도
getchar();
return 0;
}
출력 결과:
컴파일 오류 발생 (호출 가능한 기본 생성자가 존재하지 않음)
이번에는 myInteger(int v)라는 매개변수가 있는 생성자를 정의했습니다. 사용자가 생성자를 하나라도 정의하는 순간 컴파일러는 기본 생성자를 더 이상 자동 생성하지 않습니다. 따라서 인수 없이 객체를 생성하려고 하면 일치하는 생성자를 찾을 수 없다는 컴파일 오류가 발생합니다.
해결 방법
매개변수가 있는 생성자와 함께 기본 생성자도 사용하고 싶다면 다음 두 가지 방법 중 하나를 선택하면 됩니다.
- 기본 생성자를 직접 명시적으로 정의합니다.
예: myInteger() { value = 0; } - C++11 이상이라면 default 키워드를 사용해 컴파일러에 기본 생성자 생성을 요청합니다.
예: myInteger() = default;
정리
- 클래스에 생성자가 전혀 없으면 → 컴파일러가 기본 생성자를 자동으로 생성합니다.
- 사용자가 생성자를 하나라도 정의하면 → 기본 생성자는 자동으로 생성되지 않습니다.
- 두 가지 모두 필요하다면 → 기본 생성자를 직접 정의하거나 C++11의 = default 문법을 활용하세요.