1. 생성자와 소멸자
1) 생성자와 소멸자
- 생성자와 소멸자는 자동으로 호출되는 함수
- 리턴 타입 없음
- 생성자
- 객체가 생성되는 시점에서 자동으로 호출되는 멤버 함수
- 객체가 생성될 때 객체가 필요한 초기화를 위해
- "클래스이름()" 형식
- 디폴트 매개변수 사용 가능
- 소멸자
- 객체가 소멸되는 시점에서 자동으로 호출되는 멤버함수
- 객체가 소멸될 때 객체의 정리를 위해
- "~클래스이름()"형식
- 인자를 가질 수 없기 때문에 오버로딩 불가
2) 생성자 특징
- 객체 생성 시 오직 한 번만 호출
- 각 객체마다 생성자 실행
- 생성자는 중복 가능
- 생성자는 한 클래스 내에 여러 개 가능
- 중복된 생성자 중 하나 만 실행
class Circle
{
int radius;
Circle(); //클래스 이름과 동일
Circle(int r); //클래스에 대한 생성자를 2개 생성
..........................................
};
Circle::Circle() //생성자 함수 구현
{
radius = 1;
}
Circle::Circle(int r) //매개 변수를 가진 생성자 함수 구현
{
radius = r;
}
- Ex) 2개의 생성자를 가진 Circle 클래스
#include <iostream>
using namespace std;
class Circle {
public:
int radius;
Circle(); // 매개 변수 없는 생성자
Circle(int r); // 매개 변수 있는 생성자
double getArea();
};
Circle::Circle()
{
radius = 1;
cout << "반지름 " << radius << " 원 생성" << endl;
}
Circle::Circle(int r)
{
radius = r;
cout << "반지름 " << radius << " 원 생성" << endl;
}
double Circle::getArea()
{
return 3.14*radius*radius;
}
int main()
{
Circle donut; // 매개 변수 없는 생성자 호출
double area = donut.getArea();
cout << "donut 면적은 " << area << endl;
Circle pizza(30); // 매개 변수 있는 생성자 호출
area = pizza.getArea();
cout << "pizza 면적은 " << area << endl;
}
3) 디폴트 생성자
- 매개 변수가 없는 생성자(기본 생성자)
- 객체를 생성할 때 별도로 생성자를 지정하지 않으면 항상 디폴트 생성자로 초기화 됨
- 컴파일러에 의해 디폴트 생성자가 자동 생성
- 생성자가 하나라도 있는 경우 디폴트 생성자 생성 X
class Circle {
.....
Circle(); // 기본 생성자
};
4) 소멸자 특징
- 리턴 타입 선언 불가
- 중복 불가능
- 소멸자는 한 클래스 내에 오직 한 개만
- 매개 변수가 없는 함수
- 소멸자가 선언되어 있지 않으면 디폴트 소멸자가 자동 생성
- 컴파일러에 의해 디폴트 소멸자 코드 생성
- Ex) Circle 클래스에 소멸자 작성 및 실행
#include <iostream>
using namespace std;
class Circle {
public:
int radius;
Circle();
Circle(int r);
~Circle(); // 소멸자
double getArea();
};
Circle::Circle() {
radius = 1;
cout << "반지름 " << radius << " 원 생성" << endl;
}
Circle::Circle(int r) {
radius = r;
cout << "반지름 " << radius << " 원 생성" << endl;
}
Circle::~Circle() {
cout << "반지름 " << radius << " 원 소멸" << endl;
}
double Circle::getArea()
{
return 3.14*radius*radius;
}
int main()
{
Circle donut;
Circle pizza(30);
return 0;
}
5) 생성자 / 소멸자 실행 순서
- 객체가 선언된 위치에 따른 분류
- 지역 객체
- 함수 내에 선언된 객체로서, 함수가 종료되면 소멸
- 전역 객체
- 함수의 바깥에 선언된 객체로서, 프로그램이 종료할 때 소멸
- 지역 객체
- 객체 생성 순서
- 전역 객체는 프로그램에 선언된 순서로 생성
- 지역 객체는 함수가 호출되는 순간에 순서대로 생성
- 객체 소멸 순서
- 함수가 종료되면, 지역 객체가 생성된 순서의 역순으로 소멸
- 프로그램이 종료되면, 전역 객체가 생성된 순서의 역순으로 소멸
#include <iostream>
using namespace std;
class Circle {
public:
int radius;
Circle();
Circle(int r);
~Circle();
double getArea();
};
Circle::Circle() {
radius = 1;
cout << "반지름 " << radius << " 원 생성" << endl;
}
Circle::Circle(int r) {
radius = r;
cout << "반지름 " << radius << " 원 생성" << endl;
}
Circle::~Circle() {
cout << "반지름 " << radius << " 원 소멸" << endl;
}
double Circle::getArea()
{
return 3.14*radius*radius;
}
Circle globalDonut(1000); //전역 객체
Circle globalPizza(2000);
void f() {
Circle fDonut(100); //함수 안의 지역 객체
Circle fPizza(200);
}
int main()
{
Circle mainDonut; //main() 문 안의 지역 객체
Circle mainPizza(30);
f();
}
6) 객체 간의 초기화와 대입
- 같은 클래스의 객체 간에 서로 초기화나 대입이 가능
- 초기화
- 복사 생성자 이용
- 같은 클래스의 다른 객체와 같은 값을 같도록 초기화
- 클래스의 멤버 변수를 1대1로 초기화
- 복사 생성자 이용
- 대입
- 대입 연산자 이용
- 같은 클래스의 다른 객체 값을 대입
- 클래스의 멤버 변수를 1대1로 대임
- 대입 연산자 이용
Stack s1(5);
Stack s2 = s1; // 객체 간의 초기화 = 복사생성자
Stack s3;
s3 = s1; // 객체 간의 대입
2. 분할 컴파일
1) 바람직한 프로그램 작성법
- 클래스 선언부
- 헤더파일(*.h)에 저장
- 클래스 구현부
- cpp 파일(*.cpp)에 저장
- 클래스가 선언된 헤더파일을 include해야함
- main() 등 전역 함수나 변수는 다름 cpp파일에 분산 저장
- 필요 시 클래스가 선언된 헤더파일 include
- Ex)
- Circle.h(클래스 선언부)
class Circle {
private:
int radius;
public:
void SetRadis();
int GetRadius();
double getArea();
};
- Circle.cpp(클래스 구현부)
#include <iostream>
using namespace std;
#include "Circle.h"
void Circle::setRadis(int r) {
radius = r;
}
int getRadius() {
return radius;
}
double Circle::getArea() {
return 3.14*radius*radius;
}
- main.cpp
#include <iostream>
using namespace std;
#include "Circle.h"
int main() {
Circle donut;
donut.setRadius(1);
double area = donut.getArea();
cout << "donut 면적은 ";
cout << area << endl;
Circle pizza;
pizza.setRadius(30);
area = pizza.getArea();
cout << "pizza 면적은 ";
cout << area << endl;
}
2) 헤더 파일의 중복 include 문제
#include <iostream>
using namespace std;
#include "Circle.h"
#include "Circle.h" // 컴파일 오류 발생 : 'class'형식 재정의
#include "Circle.h"
int main() {
...........
}
- 조건 컴파일로 해결
- 규칙
- 헤더 파일의 이름을 따서 심볼을 생성(Ex. TEST_H )
- 헤더 파일의 제일 앞에 #ifndef, #define 명령을 추가
- 헤더 파일의 제일 끝에 #endif 명령을 추가
- 규칙
#ifndef CIRCLE_H
#define CIRCLE_H
class Circle {
private:
int radius;
public:
void setRadius(int r);
int getRadius()
double getArea();
};
#endif
'프로그래밍 언어 > C++' 카테고리의 다른 글
7) 여러가지 객체의 생성 방법 (1) | 2023.11.03 |
---|---|
6) 접근 지정자, static 멤버 (0) | 2023.11.02 |
4) 클래스와 객체의 기본 (1) | 2023.11.01 |
3) 개선된 함수 기능 (0) | 2023.11.01 |
2) 포인터와 레퍼런스 (1) | 2023.11.01 |