String Class 생성자와 제거자
:String Class의 생성자와 제거자 코드를 작성해보자
<<
1. Storage Class의 기억부류
① 자동변수 (Automatic Variables)
- 정의와 동시에 생성되고, 블럭({ })이 끝날 때 제거되는 변수
- 스택(Stack)에서 생성된다 (reentrant 가능)
② 정적변수 (Static Variables)
- 프로그램 시작과 동시에 생성되고, 프로그램이 끝날 때 제거되는 변수
- Data Segment에서 할당된다
③ 동적변수 (Dynamic Variables)
- new로 생성되고, delete로 제거되는 변수
- Heap Memory에서 생성된다
※ Storage 예시
#include <iostream>
using namespace std;
int global; //Static, 정적변수
int main(){
static ins staticvar = 10; //Static, 정적변수
char* dynamic = new char[10];//Dynamic, 동적변수
//do something
delete[] dynamic;
int local1 = 0; //Automatic, 자동변수
if(local1 == 0){
int local2; //Automatic, 자동변수
local2 = 0;
}
//do something
}
2. Constructor (생성자)
생성자란?
- 객체가 새로 만들어질 때, 자동으로 호출되는 함수를 말한다
- 객체의 초기화를 담당한다
- Class의 이름과 동일하며, Overload가 가능하다
- 리턴값이 별도로 존재하지 않는다
- Default Constructor (인자 없는 생성자)가 있으며, 이는 배열 생성 시 반드시 필요하다
상속과 생성자
- Base Class (기초클래스)의 생성자를 호출하는 방법은 아래와 같다
DerivedClass(Args) : BaseClass(Args)
{
//body
}
3. Destructor (제거자)
제거자란?
- 객체가 제거될 때 자동으로 호출되는 함수다
- 주로 객체가 할당한 리소스를 해제하는 역할을 수행한다
- 클래스의 이름 앞에 ~ (틸태)를 붙인다.
- 인자 및 리턴값이 별도로 존재하지 않는다
- 상속이 사용되는 클래스의 경우 virtual을 붙여야 한다
4. Copy Initializer Constructor (복제 생성자)
복제 생성자란?
- 같은 타입의 객체로부터 생성된(복제된) 새로운 객체를 의미한다
X::X(const X&)
※ 복제 생성자가 작동하는 경우
- 다른 객체로부터 만들어질 때
- 객체를 함수의 인자로 넘길 때
- 함수에서 객체를 리턴할 때
* 복제 생성자 생성 시 주의사항
"복제생성자가 작동하는 경우"와 "연산자 = 를 통해 생성자를 할당하는 경우"를 명확히 구분해야 한다.
String some_function(String str)
{
String strReturn;
//do something
return strReturn;
}
int main(){
String str1 = "Test String";
//복제 생성자가 작동하는 경우
String str2 = str1;
str2 = some_function(str1); //strReturn 호출
//연산자 = 를 통해 생성자를 할당하는 경우
String str3;
str3 = str1;
}
위 1 ~ 4 개념을 활용하여, 아래와 같이 String 클래스의 생성자, 제거자에 대한 코드들을 추가한다.
① String Class에 생성자, 제거자의 원형 제공
class String
{
protected:
int len;
char* m_pBuffer; //string 버퍼
void _Init();
void _Clear();
void _Copy(const char* lpsz);
public:
//constructors,destructor
String(); //default constructor
String(const String&); //copy constructor
String(char*);
String(const char*);
String(char);
String(long);
String(int);
String(double);
~String();
//operators: 추후 추가 예정
//other member functions: 추후 추가 예정
};
② String 생성자, 제거자에 대한 정의 추가
//(추가) 생성자,파괴자
String::String() {
_Init();
}
String::String(const String& stringSrc) {
_Init();
len = strlen(stringSrc.m_pBuffer);
_Copy(stringSrc.m_pBuffer);
}
String::String(const char* lpsz) {
_Init();
len = strlen(lpsz) + 1;
_Copy(lpsz);
}
String::String(char* lpsz) {
_Init();
len = strlen(lpsz) + 1;
_Copy(lpsz);
}
String::String(char ch) {
char str[2];
str[0] = ch;
str[1] = '\0';
_Init();
len = 2;
_Copy(str);
}
String::String(long l) {
_Init();
char num_char[10 + sizeof(char)];
sprintf(num_char, "%d", l);
len = strlen(num_char);
_Copy(num_char);
}
String::String(int i) {
_Init();
char num_char[10 + sizeof(char)];
sprintf(num_char, "%d", i);
len = strlen(num_char);
_Copy(num_char);
}
String::String(double d) {
_Init();
char num_char[10 + sizeof(char)];
sprintf(num_char, "%d", (int)d);
len = strlen(num_char);
_Copy(num_char);
}
String::~String() {
_Clear();
}
//(기존) void 함수
void String::_Init() {
len = 0;
m_pBuffer = 0;
}
void String::_Clear() {
if (m_pBuffer)//m_pBuffer != 0 일 때
delete[] m_pBuffer;
_Init();
}
void String::_Copy(const char* lpsz) {
if (lpsz != 0) {
m_pBuffer = new char[strlen(lpsz) + 1];//null이 저장되는 공간 +1 추가
if (m_pBuffer)
strcpy(m_pBuffer, lpsz);
}
}
③ main코드에 String 클래스 Object 초기화하기
int main() {
//Constructor Test
String str1; //default Constructor
String str2("I can do"); //Constructor
String str3(" it!!"); //Constructor
String str4('A'); //Constructor
String str5 = str4; //Copy Constructor
String str6(156); //Constructor
String str7(1.1); //Constructor
return 0;
}
※ 출력함수 printf, sprintf, snprintf
① printf ("문자열과 서식", 변수 1, 변수 2)
: 첫 번째 인자인 문자열을 화면에 출력해주는 함수이다.
int printf(const char* format,변수1,변수2,...);
※ 코드 예시
#include <stdio.h>
int main(){
char cA = 'A';
printf("The cA is %c and %d in decimal.\n",cA,cA);
}
※ printf()의 서식문자 및 특수 제어문자
서식문자 | 특수 제어 문자 | |||
구분 | 기호 | 출력 형태 | 문자 | 기능 |
정수형 | %d | 10진수 정수 | \n | 줄바꿈 |
%x | 16진수 정수 | \t | 수평 탭(tab) | |
%c | 문자 | \a | beep 음 발생 | |
실수형 | %f | 10진수 실수 (float형) | \\ | 역슬래시 문자(\) 표시 |
%e | 10진수 실수 (지수형 표기) | \" | 따옴표 문자 표시 | |
%lf | 10진수 실수 (double형) | |||
문자열 | %s | 문자열 출력 |
② sprintf (버퍼 변수, 포멧1, 포멧 2)
: printf()와 유사하면서도 다른 점은, 문자열을 출력하는 printf()와 달리 sprintf()는 버퍼로 사용될 변수가 출력된다는 점이다. 즉, char* 로 선언된 변수 안에 입력된 내용이 문자열로 담기게 된다.
int sprintf(char* buffer, const char *format, ...);
※ 코드 예시
int main() {
char buf[256];
int len;
len = sprintf(buf, "I love you %d\n",3000);
printf("%s\n", buf);
}
③ snprintf (버퍼 변수, SIZE, 포멧1, 포멧 2)
: snprintf()는 sprintf()에서 2번째 파라미터에 SIZE가 추가된 함수이다. 이 함수는 문자열의 길이를 지정하여, 버퍼 오버플로우를 막을 때 유용하다
int sprintf(char* buffer, int buf_size, const char *format, ...);
※ 해당 게시글은 개인 학습의 목적으로, 아래 강의를 수강한 후 정리한 학습노트입니다.
'C++ 프로그래밍 > 자료구조와 알고리즘' 카테고리의 다른 글
[자료구조와 알고리즘] String Class 사용법 (0) | 2024.03.01 |
---|---|
[자료구조와 알고리즘] String Class Operator Overloading (0) | 2024.02.28 |
[자료구조와 알고리즘] String Class 디자인 (0) | 2024.02.25 |
[자료구조와 알고리즘] String Class (0) | 2024.02.24 |
[자료구조와 알고리즘] C++ : OOP (0) | 2024.02.24 |