생성자와 소멸자

yu-podong·2021년 5월 11일
0

CPP

목록 보기
8/9
post-thumbnail

생성자와 소멸자


객체가 생성될 때, 생성자가 자동으로 호출된다.
객체가 소멸될 때, 소멸자가 자동으로 호출된다.

생성자

객체가 생성되는 시점에서 자동으로 호출되는 멤버 변수이다. (메모리 할당 후 실행됨)
생성자는 객체가 생성될 때 각 멤버변수를 초기화하기 위함이다.
생성자 함수 형식은 클래스이름()이고, 리턴 값이 없다.

소멸자

객체가 소멸되는 시점에서 자동으로 호출되는 멤버 변수이다. (메모리 해제 전 실행됨)
소멸자는 객체가 소멸될 때 객체의 정리를 위함이다.
소멸자 함수 형식은 ~클래스이름()이고, 리턴 값이 없다.

생성자 특징

객체 생성 시, 오직 한 번만 호출하게 된다.
그러나 자동으로 호출되는 형태이므로 직접 호출할 수 없고, 각 객체마다 생성자가 실행된다.

오버로딩이 가능하므로, 한 클래스 내에 여러 생성자 함수를 정의할 수 있다.
내부적으로 객체를 생성할 때의 매개변수를 통해 중복된 생성자 중 하나만 선택하여 실행된다.

1. 디폴트 생성자
매개 변수가 없는 생성자로, 기본 생성자라고도 부른다.
객체를 생성할 때, 별로로 지정하지 않으면 항상 디폴트 생성자로 초기화가 진행된다.

2. 매개변수가 있는 생성자
객체를 특정 값으로 초기화하는 생성자로, 생성자 인자를 전달하여 처리한다.

class student {
	private:
    		int stdNum
            	string stdName;
	public:
      		// 디폴트 생성자
      		student();
          	// 매개변수가 있는 생성자
          	studnet(int stdNum, string stdName);
}

student::student() {
	this.stdNum = 0;
    this.stdName = "";
}
student::student(int stdNum, string stdName) {
	this.stdNum = stdNum;
    this.stdName = stdName;
}

C++컴파일러는 객체가 생성될 때, 생성자를 반드시 호출하므로 생성자는 꼭 있어야 한다.
만약, 개발자가 클래스에 생성자를 작성해 놓지 않으면, 컴파일러가 자동으로 디폴트 생성자를 자동으로 생성한다.

- 디폴트 생성자가 자동으로 생성되는 경우
생성자가 하나도 작성되어 있지 않는 클래스의 경우
- 디폴트 생성자가 자동으로 생성되지 않는 경우
생성자가 하나라도 선언된 클래스의 경우

const멤버변수나 레퍼런스 멤버변수의 초기화

const변수나 레퍼런스는 생성되면서 초기화가 이루어져야하는 특별한 멤버변수이다.
즉, 객체가 메모리를 할당받은 순간에 초기화도 같이 진행되어야 하며, 변수에 값을 대입하는 형태로 작성하면 error가 발생한다.
=> 초기화 리스트를 사용해야 한다.

// 초기화 리스트의 형태
// 생성자 함수 바로 뒤에, :멤버변수이름(초기값), 멤버변수이름(초기값), .. { }

class person {
	const bloodType;
    	int age;
}
person::person(int age):bloodType("A") {
	this.age = age;
}

소멸자 특징

객체가 사라지기 전에 호출되고, 실행 도중에 동적으로 할당받은 메모리 해제, 파일 저장 및 닫기, 네트워크 닫기 등을 처리한다.

생성자와는 다르게 매개변수를 가질 수 없어 오버로딩이 불가능하여 한 클래스 내에 하나밖에 존재하지 않는다.

소멸자가 선언되어 있지 않으면, 디폴트 소멸자가 자동으로 생성된다.
이때, 생성된 디폴트 소멸자는 단순 리턴만 진행한다.

class person {
	int age;
    	person* parent	;
}
// 생성자
person::person() {
	this.age = 0;
    this.parent = new person[2];
}
// 소멸자
person::~person() {
	delete[] this.parent;
}

복사 생성자


C++에서 얕은 복사와 깊은 복사

얕은 복사(shallow copy)

c++에서 기본적으로 지원하는 복사 형태로, 객체를 복사하면 객체의 멤버를 1:1로 복사한다.
객체의 멤버 변수에 동적 메모리가 할당된 경우, 원본의 주소를 해당 변수에 저장된다.
이로 인해, 원본과 사본의 메모리 공유가 발생하는 문제가 생긴다.

깊은 복사(deep copy)

객체 복사 시, 객체의 멤버를 1:1로 복사한다.
객체에 멤버 변수에 동적 메모리를 할당한 경우에는 다음의 과정을 거친다.

  1.사본은 원본이 가진 메모리 크기만큼 별로도 동적 할당을 진행한다.
  2. 원본의 동적 메모리에 있는 내용을 사본에 복사한다.

그래서, 사본과 원본이 메모리를 공유하는 문제가 발생하지 않는다.

객체 간의 초기화와 대입

같은 클래스의 객체 간에 서로 초기화 및 대입이 가능하다.

  • 객체 간의 초기화 : 복사생성자 이용
  • 객체 간의 대입 : 대입 연산자 이용
student std1(123, "yu-podong");
student std2 = std1	//==student std2(std1) : 복사생성자를 통한 초기화
			// 만약 해당 생성자가 없다면, 컴파일러가 자동 생성
student std3;
std3 = std2;		// std2객체를 std3객체에 비트 단위로 복사

복사 생성자 (Copy constructor)

객체의 복사 생성 시, 호출되는 특별한 생성자이다.
다시말해, 같은 클래스의 객체를 이용해서 초기화하는 생성자이다.

한 클래스에 하나만 선언할 수 있고, 클래스에 대한 참조 매개변수를 가진다.

복사생성자의 원형복사생성자 호출방법
student(student &std)student std2(std1)

개발자가 클래스에 복사생성자를 작성해놓지 않으면, 컴파일러가 자동으로 디폴트 복사생성자를 만들어서 삽입한다. 이때 생성된 복사생성자는 얕은 복사를 진행한다.

0개의 댓글