개인 공부/C++

[C++] Chapter 03 정리

Koalitsiya 2023. 3. 28. 17:41

C++에서의 구조체

구조체란 연관 있는 데이터를 묶을 수 있는 문법적 장치이다.

 

C++에서 구조체는 아래의 예시와 같이 정의될 수 있다.

struct Car {
	char name[20];
    int speed;
    int fuel;
};

 

 C언어에서는 구조체 변수 선언 시에 키워드 struct가 앞에 삽입되거나 별도의 typedef 선언이 추가되어야하지만 C++에서는 아래와 같이 별도의 키워드나 typedef 선언 없이 구조체 변수를 선언할 수 있다.

//C
struct Car car1;
struct Car car2;

//C++
Car car1;
Car car2;

 

 또한 구조체 내부에 함수가 삽입되는 것을 허용하며 외부로 뺄 수도 있고, 열거형 enum을 이용해 구조체 내에서만 유효한 상수를 구조체 내부에서 선언할 수도 있다.

struct Car {
	enum {
		ID_LEN = 20,
		MAX_SPEED = 200
	};

	char name[ID_LEN];
	int speed = 0;
	int fuel;

	void ShowCarState() {
		cout << "현재속도 : " << speed << "\n";
		cout << "연료량 : " << fuel << "\n";
	}

	void Accel();
};

void Car::Accel() {
	speed += 10;
}

 

 

클래스(Class)와 객체(Object)

클래스와 구조체의 차이점

  • 키워드 struct를 이용해 정의하는 구조체와 달리 키워드 class를 이용해 정의한다.
  • 접근제어 지시자를 사용하지 않았을 때 클래스는 private으로 클래스는 public으로 선언된다.

접근제어 지시자는 아래 세 가지가 있다.

  • public : 어디서든 접근허용
  • protected : 상속관계에 놓여있을 때, 유도 클래스에서의 접근허용
  • private : 클래스 내(클래스 내에 정의된 함수)에서만 접근허용
class Car {
private:
	char name[20];
	int fuel;
	int speed;
public:
	void ShowCarState();
	void Accel();
};

void Car::ShowCarState() {
	cout << "현재속도 : " << speed << "\n";
	cout << "연료량 : " << fuel << "\n";
}

void Car::Accel() {
	speed += 10;
}

 

위 예제를 작성해보고, 지금까지 설명한 내용을 종합해보면 클래스의 정의에는 아래와 같은 특징이 있다.

  • 접근제어 지시자 A가 선언되면, 그 이후에 등장하는 변수나 함수는 A에 해당하는 범위 내에서 접근가능
  • 새로운 접근제어 지시자 B가 선언되면, 그 이후로 등장하는 변수나 함수는 B에 해당하는 범위 내에서 접근가능
  • 함수의 정의를 클래스 밖으로 빼도, 이는 클래스의 일부기에 함수 내에서 private으로 선언된 변수에 접근가능
  • class를 이용해 정의된 클래스에 선언된 변수와 함수에 별도의 접근제어 지시자를 선언하지 않으면 자동으로 private으로 선언

 

객체(Object), 멤버변수, 멤버함수

  • 객체(Object) : 사물 또는 대상
  • 멤버변수 : 클래스를 구성하는(클래스 내에 선언된) 변수
  • 멤버함수 : 클래스를 구성하는(클래스 내에 정의된) 함수

C++에서의 파일분할

 어떤 프로그램이건 하나의 파일에 모든 것을 담지는 않는다. 특히 C++에서는 클래스 별로 헤더파일과 소스 파일을 생성해서 클래스의 선언과 정의를 분리하는 경우가 많아 많은 수의 파일이 만들어진다.

 클래스 Car를 대상으로 파일을 나눌 때 보통 다음과 같이 파일을 구분한다.

  • Car.h : 클래스의 선언을 담는다.
  • Car.cpp : 클래스의 정의(멤버함수의 정의)를 담는다.

 즉, Car 클래스와 관련된 문장의 컴파일 정보로 사용되는 '클래스의 선언'은 헤더파일에 저장하여, 필요한 위치에 쉽게 포함될 수 있도록 해야 하며, '클래스의 정의'는 소스 파일에 저장해서, 컴파일이 되도록 하면 된다.

 단, 인라인 함수의 정의는 헤더파일에 포함되어야한다.

 

 이를 기반으로 하나의 파일을 아래 3개의 파일로 나눠볼 수 있다.

Car.h, Car.cpp, main.cpp

 

 

객체지향 프로그래밍의 이해

 C++은 객체지향 언어이며, 여기서 객체는 'Object', 즉 "사물, 또는 대상"을 의미하고, 객체지향 프로그래밍은 현실에 존재하는 사물과 대상, 그리고 그에 따른 행동을 있는 그대로 실체화 시키는 형태의 프로그래밍이다. 

 객체는 하나 이상의 상태 정보(데이터)와 하나 이상의 행동(기능)으로 구성이 되며, 상태 정보는 변수를 통해서, 기능은 함수를 통해서 표현된다.

class Car {
private:
	char name[20];   //상태 정보
	int fuel;		 //
	int speed;		 //
public:
	void ShowCarState();	//행동
	void Accel();		    //
};

 

 객체를 생성하기 위해선 객체 생성을 위한 '틀'을 먼저 만들어야하고 여기서 '틀'을 만드는 것이 위에서 언급되던 클래스의 정의이다.

 클래스를 기반으로하는 객체생성 방법에는 두 가지가 있으며 아래와 같다.

  • ClassName objName;                              // 일반적인 변수의 선언방식
  • ClassName * ptrObj = new ClassName;  // 동적 할당방식(힙 할당방식)

 

 또한 아래와 같이 한 객체에서 다른 객체의 함수를 호출하여 메시지를 전달할 수도 있으며, 이처럼 하나의 객체가 다른 하나의 객체에게 메시지를 전달하는 방법은 함수호출을 기반으로 하고, 이러한 형태의 함수호출을 '메시지 전달(Message Passing)이라고 한다.

class lubricator {
private:
	int price;
public:
	void initStatus(int price) {
		this->price = price;
	}
	
	int SaleFuels(int money) {
		int fuel = money / price;

		return fuel;
	}
};

class Car {
private:
	int fuel;
	int money;
public:
	void InitStatus(int fuel, int money) {
		this->fuel = fuel;
		this->money = money;
	}

	void BuyFuels(lubricator& seller, int money) {
		fuel += seller.SaleFuels(money);
		this->money -= money;
	}
};