클래스 = 붕어빵 틀
객체 = 붕어빵
클래스를 만들면 클래스와 같은 특성을 가진 객체를 만들 수 있으며,
1개의 클래스로 객체를 2개이상 생산 가능하다.
객체는 (맴버 변수, 맴버 함수)로 구성된다.
맴버변수: 변수를 담은 것
맴버함수: 함수를 담은 것
class Circle {//클래스 선언부
public:
int radius; //맴버 변수
double getArea();//맴버 함수
};
double Circle::getArea(){ //클래스 구현부
return 3.14 *radius *radius
}
위 코드는 반지름을 통해 원의 넓이를 구하는 코드이다.
클래스 선언부에서는 맴버 변수와 함수를 지정하고, 클래스 구현부에서는
함수의 기능을 구현한다.
이 때 Circle:: 의 의미는 Circle클래스의 getArea()함수를 구현하겠다는 뜻으로, 다른 동일한 이름의 함수가 다른 클래스에 존재할 수 있기 때문이다.
클래스(붕어빵틀)를 만들었다면 이 클래스의 속성을 담을 객체(붕어빵)을 만들어야 한다. 객체는 클래스의 모양(속성)대로 만들어진다.
#include <iostream>
using namespace std;
class Circle{
public:
int radius;
double getArea();
};
double Circle::get Area(){
return 3.14*radius*radius;
}
int main(){
Circle donut; //Circle클래스의 donut 객체를 만든다.
donut.radius = 1;
double area = donut.getArea();
cout << "donut의 면적은" << area <<endl;
Circle pizza; // Circle클래스의 pizza 객체를 만든다.
pizza.radius = 30;
area = pizza.getArea();
cout << "pizza의 면적은" << area <<endl;
각 객체(donut, pizza)별로 Circle의 속성인 radius, getArea();가 만들어 진것을 확인할 수 있다.
생성자란? 객체를 생성할 때 필요한 초기화 작업을 위한 구문이다.
생성자는 함수이며, 클래스의 이름과 동일하게 선언한다.
생성자함수에는 리턴 타입이 존재하지 않는다. (void도 사용하면 안된다.)
class Circle{
Circle();
Circle(int n);
};
Circle::Circle(){ //동일한 이름으로 구현부 생성
}
Circle::Corcle(int n){ //동일한 이름으로 매개변수 있는 구현부 생성
return; //리턴은 생략 가능하다.
}
#include <iostream>
using namespace std;
class Circle{
public:
int radius;
Circle();
Circle(int n);
double getArea();
};
double Circle::get Area(){
return 3.14*radius*radius;
}
Circle::Circle(){
radius = 1;
cout << "반지름 값이 1(으)로 초기화 되었습니다." << endl;
Circle::Circle(int n){
radius = n;
cout << "반지름 값이 << radius << "로 초기화 되었습니다." << endl;
int main(){
Circle donut; //Circle클래스의 donut 객체를 만든다.
// 생성자는 이 구문을 객체 생성시에 실행하는 역할이다. donut.radius = 1;
double area = donut.getArea();
cout << "donut의 면적은" << area <<endl;
Circle pizza(30); // Circle클래스의 pizza 객체를 만든다.
// 생성자는 이 구문을 객체 생성시에 실행하는 역할이다. pizza.radius = 30;
area = pizza.getArea();
cout << "pizza의 면적은" << area <<endl;
위의 코드는 객체 생성시 매개변수를 받아 초기화 할것인가? 받지 않고 1로 초기화 할 것인가를 나누어 생성자를 정의했었다. 하지만, 이로써 문제가 생기는데, 아래처럼 두 번 생성자를 정의해야하는 것이다.
Circle::Circle(){
radius = 1;
cout << "반지름 값이 1로 초기화 되었습니다." << endl;
Circle::Circle(int n){
radius = n;
cout << "반지름 값이 << radius << "로 초기화 되었습니다." << endl;
이런 생성자를 1번만 정의할 수 있는 방법이 위임 생성자 이다.
Circle::Circle() : Circle(1) {} //위임 생성자
Circle::Circle(int n) { // 타겟 생성자
radius = r;
cout << "반지름" << radius << "원 생성" << endl;
위처럼 :Circle(1)을 사용함으로 써 타겟 생성자에게 초기화 할 값인 1을 넘겨서 타겟생성자를 실행할 수 있다.
참고로, 그냥 Circle(1)을 삭제하지 않고 위임 해줘야 하는 이유는 아무 매개변수가 없는 생성자 1개(기본 생성자:defalt constructor)를 반드시 생성 해줘야 하기 때문이다.
생성자를 초기화하는 방법으로 직접 코드를 입력하는 방법도 존재하지만 아래처럼 :뒤에 초기화값을 넣어줄 수도 있다.
Circle::Circle(int a, int b) :x(a), y(b) {}
위 코드는 x=a, y=b와 같은 의미를 가진다.
class Circle {
Circle();// 정의하지 않아도, 아래의 기본생성자가 자동 생성
}
Circle::Circle(){} // 기본생성자
Circle::Circle(int n){
radius = n;
cout << "반지름 값이 << radius << "로 초기화 되었습니다." << endl;
객체가 사라지기 전에 필요한 조치를 하기 위한 함수로, 기본생성자 처럼 반드시 1개이상 있어야 하며 코드로 기술하지 않더라도 기본 소멸자가 컴파일 과정에서 생성된다.
선언부
~Circle();
구현부
Circle::~Circle(){
cout << "프로그램이 성공적으로 종료되었습니다" << endl;
전역 함수들은 프로그램이 시작될 때 data영역에 저장된다.
반면, 지역함수들은, (정적일 때) 스택영역에 저장되며 이는 생성자함수도 마찬가지다. 따라서 스택의 특징에 따라 가장 먼저 생성된 함수가 다른 내부의 함수의 recursive call 처리후 가장 마지막에 삭제된다. 반면 가장 늦게 생성된 것이 가장 빨리 삭제된다.
힙영역은 new연산자로 (동적인) 함수를 사용시 할당하며, delete하지 않으면 힙영역을 계속 점유하기 때문에 주의해야한다.
#include <iostream>
using namespace std;
// 데이터 영역에 저장되는 전역 변수들
int global_var = 10; // 전역 변수 (데이터 영역)
// 스택 영역 예제: 함수 호출 시 지역 변수는 스택에 할당됨
void stackExample() {
int local_var = 5; // 스택 영역에 할당
cout << "스택 영역의 지역 변수: " << local_var << endl;
}
// 힙 영역 예제: 동적 메모리 할당은 힙 영역에서 이루어짐
void heapExample() {
int* heap_var = new int(15); // 힙 영역에 동적 메모리 할당
cout << "힙 영역의 동적 변수: " << *heap_var << endl;
delete heap_var; // 동적 메모리 해제
}
// 데이터 영역 예제: static 변수는 함수 호출 간에도 값이 유지됨
void dataExample() {
static int static_var = 20; // 데이터 영역에 할당되는 static 지역 변수
cout << "데이터 영역의 static 변수: " << static_var << endl;
static_var++; // 지역변수임에도 static으로 값이 유지되어 다음 호출 시 증가된 값을 출력
}
int main() {
// 전역 변수 출력
cout << "전역 변수 (초기화됨): " << global_var << endl;
// 스택 영역 사용 예
stackExample();
// 힙 영역 사용 예
heapExample();
// 데이터 영역 (static 변수) 사용 예: 함수 호출 시 값이 누적됨
dataExample();
dataExample();
return 0;
}
클래스의 맴버들은 보안상 클래스 외부에서 접근할 수 있게 하면 안된다.
따라서 (선언부)의 맴버 변수는 private로 보호해주어야 하며, 맴버 함수(생성자 포함)는 public으로 선언해 주어야 한다.
인라인 함수란? 반복문 안에서 함수를 반복호출하는 recursive call을 방지하기 위해 1번만 호출하도록 코드자체를 메인함수 안으로 가져오는 구문이다.
int odd(int x){
return(x*2);
}
int main() {
int sum = 0;
for(int i=1; i<=1000; i++){
if(odd(i)){
sum+= 1;
}
}
cout << sum;
}
위 코드는 odd 함수를 1000번을 호출한다. 하지만 아래처럼 inline 구문을 추가하면 1번만 호출한다.
inline int odd(int x){
return(x*2);
}
인라인함수는 컴파일러에게 이를 유도하도록 하는것이지 '강제'가 아님으로, 주의한다.

위 코드는 (헤더파일/ 함수/ 메인함수) 로 파일을 나누어 저장한 예이다.
두 파일이 각각 컴파일하여 obj를 만들고 나면, 링킹을 통해 exe파일이 만들어진다.
참고로, 헤더파일은 따로 컴파일하지 않는다.