[C++] 객체 지향 프로그래밍 - 초기화 리스트, 연산자 오버로딩

Taeil Nam·2022년 10월 25일
0

C++

목록 보기
5/13
post-thumbnail

초기화 리스트 (Member Initializer Lists)

  • 클래스의 멤버 변수를 초기화 할 때 사용.

초기화를 해야 하는 이유

  • 초기화를 하지 않으면, 변수에 쓰레기 값이 들어가서 버그의 원인이 될 수 있음.
  • 포인터 등 주소 값을 다룰 때, 혹시 모를 문제를 대비하기 위해 초기화 수행.

장점

  • 부모 클래스 또는 멤버 클래스의 원하는 특정 생성자를 호출하여 초기화 가능.
    - (기본 생성자 호출 -> 원하는 특정 생성자 호출) 과정 없이 바로 원하는 특정 생성자 호출.
  • 참조 또는 const 자료형인 멤버 변수 초기화 가능.

예제 코드

#include <iostream>

using namespace std;

class Player
{
public:
	Player()
	{
		cout << "Player 생성자 호출" << endl;
	}

	~Player()
	{
		cout << "Player 소멸자 호출" << endl;
	}
};

class Inventory
{
public:
	Inventory()
	{
		cout << "Inventory 생성자 호출" << endl;
	}

	~Inventory()
	{
		cout << "Inventory 소멸자 호출" << endl;
	}

public:
	int _size = 10;
};

class Knight : public Player
{
public:
	Knight() : _hp(100), _damage(100) // 초기화 리스트를 사용하여 멤버 변수들 초기화.
	{
		/*
			[생성자 선처리 영역]
			- 아래 내용이 숨겨져서 먼저 실행되는 곳.
			Player();
			Inventory();
		*/
		cout << "Knight 생성자 호출" << endl;
	}

	~Knight()
	{
		cout << "Knight 소멸자 호출" << endl;
	}

public:
	int _hp;
	int _damage;
	Inventory _inventory; // Knight 클래스에 Inventory 클래스 포함.
};


int main()
{
	Knight k;

	cout << "HP = " << k._hp << endl;			// 초기화된 _hp 값(100) 출력.
	cout << "Damage = " << k._damage << endl;	// 초기화된 _damage 값(100) 출력.

	return 0;
}

연산자 오버로딩 (Operator Overloading)

  • 기존의 연산자를 재정의하여 새로운 기능으로 사용하는 것.
  • 멤버 함수로 구현하는 방법과, 전역 함수로 구현하는 방법이 있음.

연산자 오버로딩을 하지 않은 경우

  • 클래스에서 특정 연산자에 대해 어떻게 수행되어야 하는지 정의하지 않았으므로, 컴파일 에러 발생.

예제 코드

#include <iostream>

using namespace std;

class Pos
{
public:
	int _x = 0;
    int _y = 0;
};

int main()
{
	Pos pos1;
	Pos pos2;

	Pos pos3 = pos1 + pos2; // Pos 자료형의 + 연산자에 대한 내용이 없으므로 오류 발생.

	return 0;
}

멤버 연산자 함수로 연산자 오버로딩

  • a operator b 형태에서, a를 기준으로 b가 인자로 들어가서 연산자 함수가 수행됨.
    ex) pos1 + pos2 인 경우, pos1을 기준으로 pos2를 인자로 넣어 연산자 함수를 수행.

예제 코드

#include <iostream>

using namespace std;

class Pos
{
public:
	Pos operator+(const Pos& b) // 멤버 연산자 함수.
	{
		Pos pos; // 연산 결과를 저장할 객체 생성.
		pos._x = _x + b._x;	// 기준 객체의 _x + 인자로 들어간 객체의 _x 값 저장.
		pos._y = _y + b._y; // 기준 객체의 _y + 인자로 들어간 객체의 _y 값 저장.
		return pos; // 연산 결과가 저장된 pos._x, pos._y 값 반환.
	}

public:
	int _x = 1;
	int _y = 1;
};

int main()
{
	Pos pos1;
	Pos pos2;

	Pos pos3 = pos1 + pos2; // pos1 값을 기준으로 pos2의 값을 더함.

	cout << pos3._x << ", " << pos3._y << endl;

	return 0;
}

전역 연산자 함수로 연산자 오버로딩

  • a operator b 형태에서 a, b 전부 연산자 함수의 피연산자로 사용.
    ex) pos1 + pos2 인 경우, pos1, pos2를 전부 연산자 함수의 피연산자로 넣어 연산자 함수를 수행.

예제 코드

#include <iostream>

using namespace std;

class Pos
{
public:
	

public:
	int _x = 1;
	int _y = 1;
};

Pos operator+(const Pos& a, const Pos& b) // 전역 연산자 함수.
{
	Pos pos; // 연산 결과를 저장할 객체 생성.
	pos._x = a._x + b._x; // 피연산자 a._x + 피연산자 b._x 값 저장.
	pos._y = a._y + b._y; // 피연산자 a._y + 피연산자 b._y 값 저장.
	return pos; // 연산 결과가 저장된 pos._x, pos._y 값 반환.
}

int main()
{
	Pos pos1;
	Pos pos2;

	Pos pos3 = pos1 + pos2;

	cout << pos3._x << ", " << pos3._y << endl;

	return 0;
}

0개의 댓글