객체는 메모리 공간을 할당한 후 생성자 호출까지 마쳐야 객체라고 할 수 있다. 즉 생성자는 객체가 되기 위해 반드시 호출되어야하는 것인데, C++에서는 default 생성자를 두어 예외가 발생하지 않도록 한다.
class aaa
{
private:
int num;
public:
/*
* aaa(){}
*/
int GetNum()
{ return num; }
};
다음 코드에서 주석을 처리한 부분은 default 생성자이다.
new 연산자를 이용한 객체의 생성과정에서도 생성자가 호출된다.
aaa *ptr = new aaa;
class SoSimple
{
private:
int num;
public:
SoSimple(int n)
: num(n)
{
}
};
이니셜라이저로 num값에 n을 넣는 생성자를 만들었다.
이 클래스에서 SoSimple obj; 다음과 같이 객체가 생성되지 않는다.
힙에 할당된 메모리 공간은 변수로 간주, 참조자를 통한 참조가 가능하다.
#include <iostream>
using namespace std;
class AAA
{
private:
int num; //
public:
AAA() : num(0) { } //defualt 생성자
AAA& CreateInitObj(int n) const
{
AAA* ptr = new AAA(n);
return *ptr;
}
void ShowNum() const
{
cout << num << endl;
}
private: //private 생성자를 선언해 AAA 객체를 생성 및 반환
AAA(int n)
:num(n)
{
}
};
int main()
{
AAA base;
base.ShowNum(); // 0
AAA& obj1 = base.CreateInitObj(3);
obj1.ShowNum(); //3
AAA& obj2 = base.CreateInitObj(12);
obj2.ShowNum();
delete& obj1;
delete& obj2;
return 0;
}
소멸자란?
- 클래스의 이름 앞에 "~"가 붙은 형태의 이름을 가진다.
- 반환형 선언X, 실제로 반환하지 않는다
- 매개변수는 void형으로 선언되어야 하기 때문에 오버로딩도, 디폴트 값 설정도 불가능하다.
class AAA {
//empty
};
class AAA {
AAA() {}
~AAA() {}
};
다음 두 코드는 완전히 동일하다.
#include <iostream>
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:4996)
using namespace std;
class Person
{
private:
char* name;
int age;
public:
Person(const char myname[100], int myage) {
int len = strlen(myname) + 1;
name = new char[len]; //문자열 길이 만큼 메모리 공간 동적할당
strcpy(name, myname); // 멤버 변수 초기화
age = myage;
}
void ShowPersonInfo() const
{
cout << "이름 : " << name << endl;
cout << "나이 : " << age << endl;
}
~Person() {//소멸자
delete[]name;
cout << "called destructor!" << endl;
}
};
int main()
{
Person man1("aa", 2); // char *myname = "aa"
Person man2("bb", 22);
man1.ShowPersonInfo();
man2.ShowPersonInfo();
return 0;
}
Person클래스의 생성자에서 name 멤버 변수를 동적할당한 후에 값을 초기화해준다. 그리고 소멸자에서 delete로 동적할당을 해제해주고, 소멸되었음을 알린다.
> 포인터를 써서 생성자의 매개변수에 값을 넣는 방법은 없을까?
문제 04-3
문제 1
class Point
{
private:
int x;
int y;
public:
Point(int xpos, int ypos) : x(xpos), y(ypos) {}
int GetX() const;
int GetY() const;
bool SetX(int xpos);
bool SetY(int ypos);
};
이런 식으로 Member Initializer을 이용해 생성자를 정의해준다.
문제2
> 생성자에서 동적할당하는 방법 + 관련 오류 해결(?)
더보기
public:
Person(char * myname, int myage) {
int len = strlen(myname) + 1;
name = new char[len]; //문자열 길이 만큼 메모리 공간 동적할당
strcpy(name, myname); // 멤버 변수 초기화
age = myage;
}
int main()
{
Person man1("aa", 2); // char *myname = "aa"
Person man2("bb", 22);
man1.ShowPersonInfo();
man2.ShowPersonInfo();
return 0;
}
다음과 같이 main 함수를 실행하면 char 문자열에 aa를 넣을 때 인수의 자료형이 맞지 않다는 오류가 뜬다.
#include <iostream>
#pragma warning(disable:4996)
using namespace std;
namespace COMP_POS
{
enum {
CLERK, SENIOR, ASSIST, MANAGER
};
}
class NameCard {
private:
char *name; //성명
char *coo; // 회사 이름
char *tel; // 전화 번호
int level;
public:
NameCard(const char temp_name[100], const char temp_coo[100], const char temp_tel[100], int temp_level)
{
int len = strlen(temp_name) + 1;
name = new char[len]; //메모리 공간 동적 할당
strcpy(name, temp_name); // 멤버 변수 초기화
len = strlen(temp_coo) + 1;
coo = new char[len]; //메모리 공간 동적 할당
strcpy(coo, temp_coo); // 멤버 변수 초기화
len = strlen(temp_tel) + 1;
tel = new char[len]; //메모리 공간 동적 할당
strcpy(tel, temp_tel); // 멤버 변수 초기화
level = temp_level;
}
void ShowNameCardInfo()
{
cout << "이름 : " << name << endl;
cout << "회사 : " << coo << endl;
cout << "전화번호 : " << tel << endl;
switch (level)
{
case 0:
cout << "직급 : 사원" << endl;
break;
case 1:
cout << "직급 : 주임" << endl;
break;
case 2:
cout << "직급 : 대리" << endl;
break;
case 3:
cout << "직급 : 과장" << endl;
break;
}
}
};
int main()
{
NameCard manClerk("Lee", "ABCEng", "010-1111-2222", COMP_POS::CLERK);
NameCard manSENIOR("Hong", "OrangeEng", "010-3333-4444", COMP_POS::SENIOR);
NameCard manAssist("Kim", "SoGoodComp", "010-5555-6666", COMP_POS::ASSIST);
manClerk.ShowNameCardInfo();
cout << endl;
manSENIOR.ShowNameCardInfo();
cout << endl;
manAssist.ShowNameCardInfo();
}
이렇게 예제 출력을 구현해보았다.
enum 타입이 0부터 시작하는지 헷갈려서 오류가 났었다. enum은 0부터 차례로 시작하는 정수형 열거 자료형이다.
Chapter04 정리 끝!
'Langauge > C++' 카테고리의 다른 글
[열혈 C++ 프로그래밍] Chapter06 (friend와 static그리고 const) 정리 및 문제 해결 (0) | 2021.02.18 |
---|---|
[열혈 C++ 프로그래밍] Chapter05(복사 생성자) 정리 및 문제 해결 (0) | 2021.02.16 |
[열혈 C++ 프로그래밍] Chapter04(클래스의 완성) 정리 및 문제 해결 #1 (0) | 2021.02.13 |
[열혈 C++ 프로그래밍] Chapter03 - 클래스의 기본 정리 및 문제 해결 (0) | 2021.02.11 |
[열혈 C++ 프로그래밍] Chapter02 - C언어 기반의 C++ 2 (0) | 2021.02.10 |