생성자란
객체가 생성될 때마다 객체 내부와 외부에 초기화해야 할 속성들이 있습니다.
하지만 프로그램에는 많은 객체가 있기때문에, 개발자가 놓칠 수 있는데
이럴때 사용하는 것이 생성자 입니다.
생성자란 객체가 생성된 직후에 자동으로 호출되는 함수입니다.
상속 클래스의 생성자 호출순서
객체가 생성될 때 부모생성자가 먼저 호출이되고
자식의 생성자가 호출이 된다.
하지만 사라질때는 자식의 생성자가 먼저 삭제가 되고
부모의 생성자가 삭제가 된다.
생성자가 소멸할때는 마치 C언어의 이중포인터 같다.
간단하게 포인터를 A->B->C를 가르킨다라고 해볼 때
여기에서 B가 먼저 사라진다면 더이상A의 입장에서 C로 가는 길은
사라졌기 때문에 C는 메모리안 어딘가에 남아있게 되어,
메모리 누수가 생기게 될 것이다.
메모리 누수란 ? 컴퓨터 프로그램을 수행할 때 동적으로 할당된 메모리를 적절하게 회수하지 못하여, 사용할 수 있는 메모리의 크기가 줄어드는 현상이다.
또, 생성자는 클래스의 이름과 같이 생성하여야합니다.
생성자를 생성하는 패턴은 다음과 같습니다 !
기본생성자
#include <iostream>
using namespace std;
class Person {
public:
string name;
int age;
// 기본 생성자 ==> 지금 보시면 생성자와 클래스의 이름은 같습니다.
Person() {
name = "Unknown";
age = 0;
}
void display() {
cout << "Name: " << name << ", Age: " << age << endl;
}
};
int main() {
Person p; // 기본 생성자 호출
p.display();
return 0;
}
다음은 매개변수가 있는 생성자입니다.
Person(string n, int a) {
name = n;
age = a;
} // 매개변수가 있는 생성자
다음은 기본매개변수가 있는 생성자입니다.
Person(string n = "DefaultName", int a = 18) {
name = n;
age = a;
} // 기본매개변수가 있는 생성자
클래스가 생성이 될 때 생성자는 바로 생깁니다. 다음의 예시를 보면 알 수 있습니다.
#include <iostream>
using namespace std;
class Person {
public:
string name;
int age;
// 기본 생성자
Person() {
name = "Unknown";
age = 0;
cout << "생성자 !!" << endl;
}
};
int main() {
Person p; // 기본 생성자 호출
return 0;
}
위의 코드를 실행한 결과는
다음과 같은데, 단순히 메인함수에서 person p만 선언했을 뿐인데,
생성자가 생기면서 출력이 되었음을 볼 수 있습니다.
이는 정적할당이 원인이며 자세한 내용은 추후에 공부할 예정입니다.
#include <iostream>
using namespace std;
class character {
public :
character() {
cout << "character 클래스 생성자" << endl;
}
};
class skill : public character{
public :
skill() {
cout << "skill 클래스 생성자" << endl;
skill(10, 10); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
}
skill(int x, int y) : location{x,y} {
cout << "skill 클래스 생성자 매개변수" << endl;
}
void show_location() {
cout << "위치 : x , y = " << location[0] << location[1] << endl;
}
private:
int location[2];
};
int main() {
skill s;
s.show_location();
return 0;
}
해당 코드에서 skill() 생성자 내의 skill (10,10) 을 보면 원래의 의도는 나는 초기값을 10,10으로 설정하겠어!
였지만 실행결과는 달랐습니다.
이점을 보면서 의아한 점이 2개가 있었습니다. 왜 생성자가 2번 생겼는지? 그리고 위치값이 왜 제대로 들어가지 않는지?
그 이유는 다음과 같았습니다.
가장먼저 skill s를 선언하는 순간 클래스가 부모생성자 ->자식생성자로 생기게 됩니다.
그 후에 생성자 내부에서 skill(10,10)을 실행하는데 이 때 객체를 지역변수에 저장하지 않았기 때문에
skill 매개변수 생성자에서 생성되면서 값을 전달하지 못하는 상황이 벌어집니다.
따라서 위치를 제대로 받을 수가 없는데 이를 해결하기 위해 다음과 같은 초기화 방법을 사용했습니다.
class skill : public character{
public :
skill() : skill(10,10) {
cout << "skill 클래스 생성자" << endl;
}
skill(int x, int y) : location{x,y} {
cout << "skill 클래스 생성자 매개변수" << endl;
}
void show_location() {
cout << "위치 : x , y = " << location[0] << "," << location[1] << endl;
}
private:
int location[2];
};
skill생성자 옆에 : 이라는 접근지정자를 설정해서 skill매개변수생성자에 접근할 수 있게 하여 skill을 원하는 값으로 초기화 해줄수 있었습니다.
마지막으로
class character {
public :
character() : a(1), b(2) {
cout << "character 클래스 생성자" << endl;
}
void showcharacter() {
cout << a << "," << b << endl;
}
private :
int a;
int b;
};
character() 생성자 내에서 해당하는 a,b의 값을 코드처럼 수정할 수 있다.
다음 공부 할것 :
가상함수, 가상함수가 필요한 이유, 정적할당,동적할당 에 대해 공부할 예정입니다.
그 다음의 목표 :
힙메모리와 스택메모리에 대해 제대로 알고 넘어가기 , 포인터와 레퍼런스의 차이
'TIL' 카테고리의 다른 글
2024/12/27 TIL : 오버로딩과 오버라이딩 (0) | 2024.12.27 |
---|---|
2024/12/26 TIL : 가상함수와 메모리할당 (1) | 2024.12.26 |
2024 /12/23 TIL : c++ 클래스 문법 (0) | 2024.12.23 |
2024/12/18 TIL : 블루프린트로 게임 로직 만들어보기 ! (2) | 2024.12.18 |
2024/12/17 TIL : Unreal과 친해지기 (0) | 2024.12.17 |