C++/ 생성자, 기본 생성자, 복사 생성자

2025. 2. 4. 14:27·C++/개인 공부

생성자

생성하자마자 초기화를 해준다. 객체 생성시 자동으로 호출된다.

디폴트 생성자

class Date{
    ~~~
    ~~~
}

int main(void)
{
    Date day;
}

Date의 생성자를 명시하지 않아도, 생성자를 클래스내에 정의하지 않아도, 기본 생성자가 호출된다. → 컴파일러가 자동으로 추가해줌

생성자 오버로딩

생성자로 인자를 다르게 해서, 생성시 초기화할때 어떤 생성자를 사용할 것인지 선택할 수 있다.

Date day; //기본 생성자 호출
Date day2 = Date(); //기본 생성자 호출

Date day3(1, 11, 111); //사용자 정의 생성자 호출
Date day4 = Date(2, 22, 222); //사용자 정의 생성자 호출

Date day2(); //XXX 이렇게 하면 안됨.

동적할당시 new

new연산자는 객체를 동적으로 생성하면서, 동시에 자동으로 생성자로 호출해준다.

class Marine{
    ~~~
    ~~~
    Marine(); //기본 생성자
    Marine(int x, int y); //사용자 정의 생성자
}

int main(void)
{
    Marine* marine_arr[100];

    marine_arr[0] = new Marine(2, 3); //객체를 동적으로 생성하면서
    marine_arr[1] = new Marine(5, 6); //동시에 생성자 자동호출

    ~~
    ~~

    delete marine_arr[0]; //할당해제
    delete marine_arr[1];
}

소멸자

객체가 소멸할 때, 자동으로 호출되는 함수.

class Marine{
    ~~~
    ~~~
    Marine(); //기본 생성자
    Marine(int x, int y); //사용자 정의 생성자
    ~Marine(); //소멸자 (소멸자는 인자를 가지지 않는다.)
}

int main(void)
{
    Marine* marine_arr[100];

    marine_arr[0] = new Marine(2, 3); //객체를 동적으로 생성하면서
    marine_arr[1] = new Marine(5, 6); //동시에 생성자 자동호출

    ~~
    ~~

    delete marine_arr[0]; //할당해제
    delete marine_arr[1];
}

delete를 하면 객체만 사라진다. 만약에, 객체에서 또다른 메모리를 new로 할당했다면, 객체가 delete되어도 이 또 다른 메모리는 살아있다.

→ Memory Leak이 생긴다.

따라서 소멸자에서 이 또 다른 메모리를 해제시켜주어야한다.

복사 생성자

객체를 1개만 생성해 놓고, 그 한개를 가지고 나머지 객체들을 복사 생성 한다.

정의

어떤 클래스 T가 있다면T(const T& a) 로 정의한다.

다른 T의 객체 a를 상수 레퍼런스로 받는다.

또한, a가 const형식으로 a의 값들을 복사할수 있지만, 변경할 순 없다.

class Snack{
    ~~
    ~~
    Snack(int cal, int price);
}

Snack::Snack(const Snack& sn)
{
    cal = sn.cal;
    price = sn.price;
}

Snack sn1(330, 2000); //330칼로리에 가격은 2000원인 객체 생성
Snack sn2 = sn1; //복사 생성자 사용

//혹은

Snack sn2(sn1); //이렇게도 가능

복사 생성자는 오직 ‘객체 생성’시에만 호출된다.

컴파일러는 이미 디폴트 복사 생성자를 지원해준다.

BUT,

디폴트 복사 생성자의 한계

만약, 복사 생성자의 인자에 포인터가 있다면, 문제가 된다.

class Snack
{
    int cal;
    int price;
    char* name;
    ~~
    ~~

    Snack(int cal, int price, char* snack_name);
    ~Snack();
}

Snack::Snack(int cal, int price, char* snack_name)
{
    this.cal = cal;
    this.price = price;
    this.snack_name = snake_name;
}

~~
~~
Snack sn1 = Snack(330, 2000, "potato chip");
Snack sn2 = sn1; //복사생성자를 사용해서 복사

sn1의 과자 이름은 “potato chip”이다.

Snack sn2 = sn1; 문장을 실행할 때, 컴파일러는 자동으로 기본 복사 생성자를 만들어서 객체의 요소를 하나하나 복사한다.

this.cal = sn1.cal;
this.price = sn1.price;
this.name = sn1.name;

이런식으로 복사를 하는데, 문제는 char*형인 name은 포인터라는 것이다.

그러면, sn1.name과 sn2.name은 같은 메모리 공간을 가리키게된다.

같은 메모리 공간을 가리키는건 문제가 되지 않지만, 문제는 소멸자에서 발생한다.

sn1이 소멸하면 자동으로 sn1.name포인터는 메모리 공간에서 사라지게되고, sn2가 소멸할때는 이미 소멸되고 없는 sn2.name을 소멸시키려고 하기 때문이다. → 한번 해제된 메모리를 접근하여 또 해제하려고함!

해결법

포인터 자체를 복사하지말고, 다른 부분에 동적할당을 해서, 그 내용만 복사하면 될 것이다.

Snack::Snack(const Snack& sn)
{
    this.cal = sn.cal;
    this.price = sn.price;

    this.name = new char[strlen(sn.name) + 1]; //동적할당해서
    strcpy(this.name, pc.name); //내용을 복사한다.
}

얕은 복사(shallow copy), 깊은 복사(deep copy)

문제가 생겼던 단순한 복사 방식을 shallow copy

해결한 복사 방식을 deep copy라고 한다.

'C++ > 개인 공부' 카테고리의 다른 글

C++/참조자(레퍼런스)  (0) 2025.02.01
가상 함수와 오버라이딩  (0) 2023.06.07
'C++/개인 공부' 카테고리의 다른 글
  • C++/참조자(레퍼런스)
  • 가상 함수와 오버라이딩
Jminu
Jminu
  • Jminu
    뇌 구조가 바이너리
    Jminu
  • 전체
    오늘
    어제
    • 분류 전체보기
      • C프로그래밍
        • 오류해결
        • 개인 공부
        • Programming Lab(학교수업)
        • MemoryTracker
      • C++
        • 개인 공부
      • 자료구조(Data Structure)
      • ARM arch
        • Cortex-M
        • FreeRTOS
      • 컴퓨터 공학(Computer Science)
        • OS
        • 컴퓨터 구조
      • Qualcomm 기업과제
      • Linux
      • Web
      • 똥글
      • 백준
      • Git 학습
        • 오류해결
        • 학습중
      • Python
        • 오류해결
        • 개인 공부
  • 블로그 메뉴

    • 태그
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    c언어
    yolo
    C++
    스택
    자료구조
    피보나치
    memory mapped io
    포인터
    버퍼
    동적메모리
    백준
    파일 입출력
    과속탐지
    소수
    ptrace
    Git
    커널
    Branch
    commit
    Qualcomm
    이진 트리
    파이썬
    arm
    aapcs
    exception vector table
    rubik pi
    rubikpi3
    INIT
    순환
    thumb2
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Jminu
C++/ 생성자, 기본 생성자, 복사 생성자
상단으로

티스토리툴바