πŸ€“ Study/C++ & C#

03. C++ μ£Όμš” κΈ°λŠ₯ & μƒμ„±μž/μ†Œλ©Έμž/λ³΅μ‚¬μƒμ„±μž

GAMEMING 2024. 3. 20. 00:41
728x90

 

 

- C++ μ£Όμš” κΈ°λŠ₯ ( 좔상화, 정보 은닉, μΊ‘μŠν™”)

#include <iostream>
using namespace std;

// C++ μ£Όμš” κΈ°λŠ₯

// 1. 좔상화(abstracton)
// : 사물을 μ‚¬μ‹€μ μœΌλ‘œ ν‘œν˜„ν•˜λŠ” κ°œλ…(ꡬ상화)κ°€ μ•„λ‹Œ
//   λΆˆν•„μš”ν•œ 뢀뢄은 μ œκ±°ν•˜κ³  κ³΅ν†΅λœ νŠΉμ§•λ§Œμ„ μΆ”μΆœν•˜λŠ” 것

// ex) 슀마트폰 -> User : λ‚΄λΆ€ 섀계 λͺ¨λ₯΄μ§€λ§Œ, 잘 μ‚¬μš©ν•¨ (μ™ΈλΆ€ μΈν„°νŽ˜μ΄μŠ€ - λ‚΄λΆ€ κ΅¬ν˜„)

// 2. 데이터 은닉(Data hiding)
// : 객체의 속성을 숨기고 곡개된 μΈν„°νŽ˜μ΄μŠ€λ§Œμ„ ν†΅ν•΄μ„œ μˆ˜μ •ν•  수 μžˆλ„λ‘ 함

// 3. μΊ‘μŠν™”(Capsulation)
// : 객체의 속성과 κΈ°λŠ₯을 ν•˜λ‚˜λ‘œ λ¬Άκ³ , μ„ΈλΆ€ κ΅¬ν˜„μ€ 클래슀 μ•ˆμœΌλ‘œ μˆ¨κΈ°λŠ” 것
//  잘 λ˜μ–΄ μžˆλŠ” ν΄λž˜μŠ€λŠ” μž¬ν™œμš©λ„κ°€ 맀우 λ†’λ‹€

// μ•„λž˜λŠ” μΊ‘μŠν™”κ°€ 잘λͺ»λœ μ˜ˆμ œμ΄λ‹€.

class File {
public:
	void load()
	{
		cout << "mp3 νŒŒμΌμ„ λ©”λͺ¨λ¦¬μ— μ˜¬λ¦°λ‹€." << endl;
	}
};

class PowerDevice {
public:
	void PowerUp()
	{
		cout << "mp3 playλ₯Ό μœ„ν•œ νŒŒμ›Œλ₯Ό μ˜¬λ¦°λ‹€." << endl;
	}
};

class Memory {
public:
	void expand()
	{
		cout << "mp3 playλ₯Ό μœ„ν•œ λ©”λͺ¨λ¦¬λ₯Ό λŠ˜λ¦½λ‹ˆλ‹€." << endl;
	}
};

class Mp3 {
public:
	void play()
	{
		cout << "mp3λ₯Ό playν•©λ‹ˆλ‹€" << endl;
	}
};

int main()
{
	PowerDevice pd;
	Memory m;
	File f;
	Mp3 mp;

	pd.PowerUp();
	m.expand();
	f.load();
	mp.play();
}

//  UserλŠ” mp3λ₯Ό μ‚¬μš©ν•˜λ €λ©΄ μž¬μƒ κΈ°λŠ₯λ§Œμ„ μ‚¬μš©ν•˜λ©΄ λœλ‹€.
//  mp3의 μ„ΈλΆ€κ΅¬ν˜„μ€ μˆ¨κΈ°λ„λ‘ ν•˜λŠ” 것이 μΊ‘μŠν™” μ•„λž˜μ˜ 예제 μ°Έκ³ ν•˜μž
#include <iostream>
using namespace std;

// mp3의 playκΈ°λŠ₯λ§Œμ„ μ‚¬μš©ν•¨μœΌλ‘œ
// 이 mp3 클래슀λ₯Ό μ‚¬μš©ν•˜λŠ” μœ μ €λŠ” μ„ΈλΆ€ κ΅¬ν˜„μ— λŒ€ν•΄ λͺ°λΌλ„ 됨

class File {
public:
	void load()
	{
		cout << "mp3 νŒŒμΌμ„ λ©”λͺ¨λ¦¬μ— μ˜¬λ¦°λ‹€." << endl;
	}
};

class PowerDevice {
public:
	void PowerUp()
	{
		cout << "mp3 playλ₯Ό μœ„ν•œ νŒŒμ›Œλ₯Ό μ˜¬λ¦°λ‹€." << endl;
	}
};

class Memory {
public:
	void expand()
	{
		cout << "mp3 playλ₯Ό μœ„ν•œ λ©”λͺ¨λ¦¬λ₯Ό λŠ˜λ¦½λ‹ˆλ‹€." << endl;
	}
};

class Mp3 {
private:
	File f;
	PowerDevice pd;
	Memory m;

public:
	void play()
	{
		pd.PowerUp();
		m.expand();
		f.load();
		cout << "mp3 play" << endl;
	}
};

int main()
{
	Mp3 mp;
	mp.play();
}

 

 

 

 

- μƒμ„±μž

#include <iostream>
using namespace std;

#define NAME_LEN 20
#define SEX_LEN 10
#define JOB_LEN 20
#define CHARACTER_LEN 20

class Person {
private:
	char name[NAME_LEN];
	char sex[SEX_LEN];
	char job[JOB_LEN];
	char character[CHARACTER_LEN];
	int age;
	bool marriageStatus;
public:
	// λ””ν΄νŠΈ μƒμ„±μž
	Person()
	{
		cout << "λ””ν΄νŠΈ μƒμ„±μž : Person::Person()" << endl;
		// λ³€μˆ˜ μ΄ˆκΈ°ν™”
	}

	// μ €λ²ˆ μ‹œκ°„μ— ν–ˆλ˜ constructor와 같은 κΈ°λŠ₯을 μˆ˜ν–‰ν•˜λŠ” μƒμ„±μž
	// 멀버 μ΄ˆκΈ°ν™”λ₯Ό μ΄μš©ν•œ μƒμ„±μž
	Person(const char* name, const char* sex, const char* job,const char* character,
		int age, bool marriageStatus);      // μƒμ„±μž μ„ μ–Έ
	void introduce();
	void eat(const char* food);
	void sleep();
	void drive(const char* dest);
	void write();
	void read();
};

int main()
{
	// Person player1, player2;

	//player1.constructor("예슬", "μ—¬μ„±", "μ½”λ”©μ²œμž¬", "온순", 21, true);
	// player2.constructor("μ’…λͺ…", "남성", "μš”μ–‘μ›", "μ„±μ‹€", 23, false);

	Person player1("예슬", "μ—¬μ„±", "μ½”λ”©μ²œμž¬", "온순", 21, true);
	Person player2("μ’…λͺ…", "남성", "μš”μ–‘μ›", "μ„±μ‹€", 23, false);

	player1.introduce();
	player2.introduce();

	player1.eat("λ§ˆλΌνƒ•");
}

 Person::Person(const char* name, const char* sex, const char* job, const char* character, int age, bool marriageStatus)
{
	strcpy_s(this->name, name);
	strcpy_s(this->sex, sex);
	strcpy_s(this->job, job);
	strcpy_s(this->character, character);
	this->age = age;
	this->marriageStatus = marriageStatus;

	cout << "μƒμ„±μž : Person::Person(~)" << endl;
}

void Person::introduce()
{
	cout << "이름 : " << name << endl;
	cout << "성별 : " << sex << endl;
	cout << "직업 : " << job << endl;
	cout << "성격 : " << character << endl;
	cout << "λ‚˜μ΄ : " << age << endl;
	cout << "결혼 μ—¬λΆ€ : " << (marriageStatus ? "YES" : "NO") << endl;
}

void Person::eat(const char* food)
{
	cout << name << "은(λŠ”) " << food << "λ₯Ό λ¨ΉλŠ”λ‹€" << endl;
}

void Person::sleep()
{
	cout << name << "은(λŠ”) μž”λ‹€" << endl;
}

void Person::drive(const char* dest)
{
	cout << name << "은(λŠ”) " << dest << "으둜 μš΄μ „ν•œλ‹€" << endl;
}

void Person::write()
{
	cout << name << "은(λŠ”) 책을 μ“΄λ‹€" << endl;
}

void Person::read()
{
	cout << name << "은(λŠ”) 책을 μ½λŠ”λ‹€" << endl;
}


// 01) μƒμ„±μž μ„ μ–Έ
// - ν•΄λ‹Ή 클래슀의 이름과 κ°™μ•„μ•Ό ν•˜λ©°, λ°˜ν™˜ν˜•μ΄ μ—†μ–΄μ•Ό ν•œλ‹€

// 02) μƒμ„±μž ν˜ΈμΆœν•˜λŠ” 곳은 어디인가?
// - 객체 생성을 μœ„ν•œ λ©”λͺ¨λ¦¬ 곡간 ν• λ‹Ήκ³Ό λ™μ‹œμ— μƒμ„±μžκ°€ ν˜ΈμΆœλœλ‹€.
// - ν˜„μž¬μ˜ μ½”λ“œμ—μ„œ 객체λ₯Ό 생성과 λ™μ‹œμ— μ΄ˆκΈ°ν™” ν•˜κ³  μžˆλ‹€.

// 03) 같은 μ΄λ¦„μœΌλ‘œ μ—¬λŸ¬ 개 λ§Œλ“€ 수 있으며 (ν•¨μˆ˜ μ˜€λ²„λ‘œλ”©)

// 04) μƒλž΅ κ°€λŠ₯ν•˜λ‹€ (λ””ν΄νŠΈ μƒμ„±μž μžλ™ 생성)
// -> λ””ν΄νŠΈ μƒμ„±μž(κΈ°λ³Έ μƒμ„±μž)
// μš°λ¦¬κ°€ μž‘μ„±ν–ˆλ˜ μ½”λ“œμ—μ„œ μƒμ„±μžλ₯Ό μ§€μš°λ©΄? -> λŒμ•„κ°€κΈ΄ ν•˜λ‚˜ μ“°λ ˆκΈ° κ°’.

 

 

 

- μ†Œλ©Έμž

#include <iostream>
using namespace std;

// μ†Œλ©Έμž(deconstructor)
// 객체가 μ†Œλ©Έν•  λ•Œ μžλ™ 호좜
// 동적 λ©”λͺ¨λ¦¬λ₯Ό ν•΄μ œν•˜λŠ” μš©λ„λ‘œ μ‚¬μš©
// μƒλž΅ κ°€λŠ₯

// 동적 λ©”λͺ¨λ¦¬
// cμ–Έμ–΄ - malloc(), free(0
// c++ - new, delete

// strcpy_s
// - 첫 번째 λ§€κ°œλ³€μˆ˜λ‘œ 받은 λ©”λͺ¨λ¦¬μ—
// 두 번째 λ§€κ°œλ³€μˆ˜λ‘œ 받은 길이만큼
// μ„Έ 번째 λ§€κ°œλ³€μˆ˜μ˜ λ‚΄μš©μ„ 볡사


class Person {
private:
	char* name;
public:
	Person(const char* name) //μƒμ„±μž
	{
		this->name = new char[strlen(name) + 1];    // 동적할당
		strcpy_s(this->name, strlen(name) + 1, name);
		cout << "Person::Person(name) μƒμ„±μž μ™„λ£Œ" << endl;
	}

	Person()
	{
		cout << "Person::Person() μƒμ„±μž μ™„λ£Œ" << endl;
	}

	~Person() // μ†Œλ©Έμž
	{
		delete[] name;
		cout << "Person::~Person μ†Œλ©Έμž μ™„λ£Œ" << endl;
	}

	void introduce();
};

int main()
{
	Person person("미영");
	person.introduce();

}

void Person::introduce()
{
	cout << "이름: " << name << endl;
}

 

 

 

- 볡사 μƒμ„±μž

#include <iostream>
using namespace std;

// 볡사 μƒμ„±μž (볡사할 λ•Œ ν˜ΈμΆœλ˜λŠ” μƒμ„±μž)
// - λ¨Όμ € μƒμ„œμ™Ό 객체λ₯Ό μ΄μš©ν•΄μ„œ μƒˆλ‘œμš΄ 객체 μ΄ˆκΈ°ν™”ν•˜λŠ” 경우
// - λ¨Όμ € μƒμ„±ν•œ 객체λ₯Ό 인자둜 μ „λ‹¬ν•˜λŠ” 경우
// - ν•¨μˆ˜ λ‚΄μ—μ„œ 객체λ₯Ό λ°˜ν™˜ν•˜λŠ” 경우

// μ•„λž˜μ˜ μ½”λ“œμ—μ„œ μ†Œλ©Έμž 2번 호좜 -> 이유

class Person {
private:
	int age;
	int num;
public:
	Person(int age) : age(age) //μƒμ„±μž
	{
		cout << "Person::Person(age) μƒμ„±μž μ™„λ£Œ" << endl;
	}

	Person()
	{
		cout << "Person::Person() μƒμ„±μž μ™„λ£Œ" << endl;
	}

	~Person() // μ†Œλ©Έμž
	{
		cout << "Person::~Person μ†Œλ©Έμž μ™„λ£Œ" << endl;
	}

	void introduce();
};

int main()
{
	Person person1(23);
	Person person2(person1);  // λ³΅μ‚¬μƒμ„±μž 호좜
	// person2 = person1;

	person1.introduce();
	person2.introduce();
}

void Person::introduce()
{
	cout << "λ‚˜μ΄ : " << age << endl;
}

 

μœ„μ˜ μ½”λ“œ
μ•„λž˜μ˜ μ½”λ“œ, 얕은 λ³΅μ‚¬μ˜ 문제

 

 

#include <iostream>
using namespace std;

// λ””ν΄νŠΈ 볡사 μƒμ„±μž -> 문제 쑴재
// 얕은 볡사 vs κΉŠμ€ 볡사
// λ””ν΄νŠΈ 볡사 μƒμ„±μžλŠ” 멀버 λ³€μˆ˜μ˜ 값을 λ³΅μ‚¬νžˆκΈ°μ—,
// λ©”λͺ¨λ¦¬ μ£Όμ†Ÿκ°’μ„ λ³΅μ‚¬ν•˜κ²Œ 됨  -> 문제 λ°œμƒ

// μ•„λž˜μ˜ μ½”λ“œ λŸ°νƒ€μž„ 였λ₯˜ λ°œμƒ
// - 볡사 μƒμ„±μž ν˜ΈμΆœμ— μ˜ν•΄ 멀버 λ³€μˆ˜ κ°’ 볡사인 얕은 볡사가 μ§„ν–‰
// - person1 객체의 name ν¬μΈν„°μ˜ 값인 'μ£Όμ†Œ1'이 person의 name 포인터 κ°’μœΌλ‘œ 볡사
// - 즉 같은 λ©”λͺ¨λ¦¬ 곡간을 κ°€λ₯΄ν‚€κ²Œ 됨
// - μ†Œλ©Έμžκ°€ ν˜ΈμΆœλ¨μ— 따라 (μ†Œλ©ΈμžλŠ” μ—­μˆœμœΌλ‘œ 호좜됨) person2 객체 μ†Œλ©Έ
// - 이어 person1의 μ†Œλ©Έμž ν˜ΈμΆœλ˜λ €λŠ” μ°°λ‚˜ deleteλ˜μ–΄μ•Ό ν•˜λŠ” λ©”λͺ¨λ¦¬ 곡간이 μ—†μ–΄ 였λ₯˜

// => κΉŠμ€ λ³΅μ‚¬μ˜ ν•„μš”
// -> 볡사 μƒμ„±μžμ˜ μž¬μ •μ˜ ν•„μš”
// -> ν¬μΈν„°μ˜ κ°’λ§Œμ„ λ³΅μ‚¬ν•˜λŠ”κ²Œ μ•„λ‹Œ,
//  포인터가 κ°€λ¦¬ν‚€λŠ” λ©”λͺ¨λ¦¬μ˜ λ‚΄μš©κΉŒμ§€ 볡사해야 함
// => 주석 ν’€κ³  μ‹€ν–‰

class Person {
private:
	char* name;
public:
	Person(const char* name)   //μƒμ„±μž
	{
		this->name = new char[strlen(name) + 1];
		strcpy_s(this->name, strlen(name) + 1, name);
		cout << "Person::Person(name) μƒμ„±μž μ™„λ£Œ" << endl;
	}

	Person()
	{
		cout << "Person::Person() μƒμ„±μž μ™„λ£Œ" << endl;
	}

	~Person() // μ†Œλ©Έμž
	{
		delete[] name;
		cout << "Person::~Person μ†Œλ©Έμž μ™„λ£Œ" << endl;
	}

	/*
	Person(const Person& p)
	{
		this->name = new char[strlen(p.name) + 1];    // name포인터 값을 μœ„ν•œ λ©”λͺ¨λ¦¬ μƒˆλ‘œ ν• λ‹Ή
		strcpy_s(this->name, strlen(p.name) + 1, p.name);  // λ©”λͺ¨λ¦¬μ— 볡사
		cout << "Person::Person(cosnt Person&) λ³΅μ‚¬μƒμ„±μž μ™„λ£Œ" << endl;
	}
	*/

	void introduce();
};

int main()
{
	Person person1("μ£Όλ…Έ");
	Person person2(person1);  // λ³΅μ‚¬μƒμ„±μž 호좜
	// person2 = person1;

	person1.introduce();
	person2.introduce();
}

void Person::introduce()
{
	cout << "이름 : " << name << endl;
}