[cpp] constructor

minjubyeon·2025년 6월 14일

cpp

목록 보기
22/26

1. Default parameter 없는 생성자

✅ 생성자의 parameter x를 받아서,
✅ 멤버 변수 x초기화하고 싶지만,
default parameter원하지 않는다


📦 잘못된 예제

class Base {
    int x;

public:
    Base() : x(x) {};  // ❌ 문제: x(x)에서 오른쪽 x는 정의되지 않음
};
  • 생성자 B()parameter가 없음 → 그런데 x(x)에서 오른쪽 x는 지역 변수인데 그런 게 없음 → 컴파일 에러

  • 즉, x = x;에서 두 개의 x 모두 같은 멤버 변수인데, 오른쪽 x는 아직 초기화되지 않았으므로 이건 초기화가 아닌 자기 자신에게 초기화를 시도하는 꼴 → 컴파일 에러!


🔧 올바른 방법

class Base {
    int x;

public:
    Base(int x) : x(x) {}
};

여기서 x(x)의 의미는:

  • 왼쪽 x: 멤버 변수 Base::x
  • 오른쪽 x: 생성자 파라미터 int x

💡 멤버와 파라미터 이름이 같을 경우엔 이니셜라이저 리스트가 우선 멤버를 초기화하므로, 이름이 같아도 헷갈리지 않아.
(혹은 this->x = x;처럼 써도 되지만 이니셜라이저 리스트가 더 효율적이야)


📌참고: 생성자의 다양한 선언

코드의미
C();클래스 안에서 → 기본 생성자 "선언"
C() {}클래스 안에서 → 기본 생성자 "정의"
C c1();⚠️ 함수 선언 (객체 아님)
C c1;객체 생성 (기본 생성자 호출)

🔚 결론

class Base {
    int x;
public:
    Base(int x) : x(x) {}
};

이게 너가 원하는 정확한 코드야.
❌ default parameter 없이,
✅ 생성자 인자로 받은 x를 멤버 변수에 대입하는 가장 깔끔한 방법이야.




3. 생성자의 첫 번째 괄호

❌ Base() : x(x) {}가 컴파일 에러인 이유

class Base {
    int x;

public:
    Base() : x(x) {}  // ❌ 에러
};
  • 이 생성자는 파라미터가 없음

  • 그런데 x(x)는 오른쪽 x가 undefined 식별자

  • 즉, x = x;에서 두 개의 x 모두 같은 멤버 변수인데, 오른쪽 x는 아직 초기화되지 않았음

  • 이건 초기화가 아닌 자기 자신에게 초기화를 시도하는 꼴 → 컴파일 에러!



✅ Data() : v(N) {}가 에러가 아닌 이유

template <typename T, int N>
class Data {
    std::vector<T> v;

public:
    Data() : v(N) {}  // ✅ 정상
};
  • N은 템플릿 인자로 정수값이 이미 주어져 있음
  • 이 괄호 안이 비어 있다는 건: "사용자가 객체를 생성할 때, 아무 인자도 전달하지 않아도 된다"는 뜻
Data<int, 3> d1;  // 괄호 없이 객체 생성 → 이때 Data()가 호출됨
  • 이건 C++에서 기본 생성자 (default constructor) 라고 부릅니다.


3. 객체의 선언과 생성자의 호출

Data<int, 3> d;

이 자체는 생성자 호출이 아닙니다. “객체를 선언”하는 문장입니다.
하지만 👉 이때 생성자가 자동으로 호출됩니다.

코드의미
Data<int, 3> d;d라는 이름의 Data<int, 3> 객체 생성
Data<int, 3>템플릿 클래스 Data를 타입 int, 크기 3으로 특수화
d객체 이름
;기본 생성자를 자동으로 호출

즉, 이 코드는:

Data<int, 3> 타입의 d라는 객체를 만들며,
기본 생성자 Data()를 자동 호출한다”는 뜻입니다.


📦 예제 : 기본 생성자의 호출

class A {
public:
    A() { std::cout << "기본 생성자 호출됨\n"; }
};

int main() {
    A a;  // 생성자 직접 안 썼지만, A()가 자동으로 호출됨
}
  • a;는 그냥 선언처럼 보이지만,
  • 실제로는 A() 생성자가 자동으로 호출됨

📦 예제 : 생성자와 다른 객체 초기화

Data<int, 3> d(0, 5);

🔹 Data<int, 3>

  • Data는 템플릿 클래스예요.
  • int는 벡터의 원소 타입
  • 3은 N이라는 템플릿 인자 → 즉, "3개의 원소를 가지는 데이터"를 의미해요.

🔹 d(0, 5)

  • 생성자를 호출하는 부분이에요.
  • 0은 초기값 → 모든 원소를 0으로 초기화할 거고
  • 5는 벡터 크기(size) → 즉, std::vector v(5, 0);로 동작함

❌ 문제점

Data<int, 3> 라고 N = 3으로 고정했는데, (0, 5)에서 크기를 5로 주는 건 앞뒤가 안 맞는 거예요

의미
템플릿에서 지정한 크기3
생성자에서 요청한 크기5
실제 생성되는 vector 크기5

이러면 Data<int, 3>는 “크기 3”으로 보이지만, 실제로는 5개의 데이터를 가짐 → 논리 오류


🔚 결론

  • Data<int, 3> d; → 객체 정의/선언
  • 생성자 직접 호출한 건 아니지만, 컴파일러가 자동으로 생성자 호출함
  • 따라서 이것도 결국 생성자가 실행되는 효과가 있음


profile
안녕하세요.

0개의 댓글