🧐 Study/C++ & C#

04. μ—°μ‚°μž μ˜€λ²„λ‘œλ”© / 이동 μƒμ„±μž&이동 λŒ€μž… μ—°μ‚°μž / 동적 λ©”λͺ¨λ¦¬

GAMEMING 2024. 3. 27. 21:00

 

< μ—°μ‚°μž μ˜€λ²„λ‘œλ”© >

#include <iostream>
#include "save.h"
using namespace std; 

// μ•„λž˜μ˜ main이 λŒμ•„κ°€λ„λ‘ μ½”λ”©ν•΄λ³΄μž

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

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

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

	void introduce();

	Person add(const Person& p);
	Person sub(const Person& p);
	Person mul(const Person& p);
	Person div(const Person& p);
};

int main()
{
	Person player(30);
	Person enemy(15);
	player.introduce();
	enemy.introduce();

	Person addPlayer = player.add(enemy);
	addPlayer.introduce();

	Person subPlayer = player.sub(enemy);
	subPlayer.introduce();

	Person mulPlayer = player.mul(enemy);
	mulPlayer.introduce();

	Person divPlayer = player.div(enemy);
	divPlayer.introduce();
}

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

Person Person::add(const Person& p)
{
	Person m(this->age + p.age);
	return m;
}

Person Person::sub(const Person& p)
{
	Person m(this->age - p.age);
	return m;
}

Person Person::mul(const Person& p)
{
	Person m(this->age * p.age);
	return m;
}

Person Person::div(const Person& p)
{
	Person m(this->age / p.age);
	return m;
}
// mainν•¨μˆ˜μ˜ .add 역할을 +κ°€ ν•  순 μ—†μ„κΉŒ? => .operator+

// 컴파일러 -> +λ₯Ό λ§Œλ‚˜λ©΄ operator+() 멀버 ν•¨μˆ˜λ₯Ό μ°Ύκ³ 
// 이의 λ©€λ²„ν•¨μˆ˜ μ™Όμͺ½κ³Ό 였λ₯Έμͺ½μ„ μ‚΄νŽ΄λ³΄κ³  μˆ˜ν–‰ν•œλ‹€.

// λ‹€μŒμœΌλ‘œ λ°”κΏ€ 수 μžˆλ‹€.

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

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

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

	void introduce();

	Person operator+(const Person& p);
	Person operator-(const Person& p);
	Person operator*(const Person& p);
	Person operator/(const Person& p);
};

int main()
{
	Person player(30);
	Person enemy(15);
	player.introduce();
	enemy.introduce();

	Person addPlayer = player + enemy;      // + 3 을 ν•˜λ©΄ ? => ν˜•λ³€ν™˜μ„ 톡해 객체가 ν•˜λ‚˜ 더 λ§Œλ“€μ–΄μ Έ κ·ΈλŒ€λ‘œ μˆ˜ν–‰λ¨
	addPlayer.introduce();

	Person subPlayer = player - enemy;
	subPlayer.introduce();

	Person mulPlayer = player * enemy;
	mulPlayer.introduce();

	Person divPlayer = player / enemy;
	divPlayer.introduce();
}

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

Person Person::operator+(const Person& p)
{
	Person m(this->age + p.age);
	return m;
}

Person Person::operator-(const Person& p)
{
	Person m(this->age - p.age);
	return m;
}

Person Person::operator*(const Person& p)
{
	Person m(this->age * p.age);
	return m;
}

Person Person::operator/(const Person& p)
{
	Person m(this->age / p.age);
	return m;
}
// mainν•¨μˆ˜
Person addPlayer = 3 + enemy;           // μ™œ μ•ˆλ κΉŒ?

// + μ—°μ‚°μžλ₯Ό 보고 operator μ—°μ‚°μžλ₯Ό μ°ΎλŠ”λ°
// 3 + λ₯Ό λ΄μ„œλŠ” μ–΄λ–€ ν΄λž˜μŠ€μΈμ§€ μ•Œ 수 μ—†μŒ
// 클래슀 λ‚΄λΆ€ ν•¨μˆ˜λ‘œλ§Œ μ •μ˜ν•˜λŠ” 것이 μ•„λ‹Œ 일반 μ „μ—­ ν•¨μˆ˜λ‘œ μ •μ˜ κ°€λŠ₯ν•˜λ‹€.

// Person class λ‚΄λΆ€
friend Person operator+(const Person& p, const Person& pp);

// μ •μ˜λΆ€λΆ„
Person operator+(const Person& p, const Person& pp)
{
	Person m(p.age + pp.age);
	return m;
}

// μ˜€λ²„λ‘œλ”© λ˜ν•œ κ°€λŠ₯ν•˜λ‹€


// * friend
// μžμ‹ μ˜ 개체뿐만이 μ•„λ‹Œ λ‹€λ₯Έ νƒ€μž…μ˜ 개체λ₯Ό μ ‘κ·Ό κ°€λŠ₯
// ν•˜λ‚˜μ˜ ν΄λž˜μŠ€μ—μ„œ λ‹€λ₯Έ 클래슀의 λ‚΄λΆ€ 데이터에 μ ‘κ·Ό ν•΄μ•Όν•  경우
// ν•¨μˆ˜λ‚˜ 클래슀 μ„ μ–Έ μ•žμ— μ„ μ–Έν•  수 있고 μ ‘κ·Ό μ œμ–΄ μ§€μ‹œμž 영ν–₯을 λ°›μ§€ X
// λ³΅μ‚¬μƒμ„±μžμ™€ 짝인 λ³΅μ‚¬λŒ€μž…μ—°μ‚°μž
// λ³΅μ‚¬μƒμ„±μž -> 객체λ₯Ό 같은 ν˜•μ‹(클래슀)의 객체둜 μ΄ˆκΈ°ν™”ν•  λ•Œ ν˜ΈμΆœλ˜λŠ” ν•¨μˆ˜
// 볡사 λŒ€μž… μ—°μ‚° -> 같은 ν˜•μ‹μ˜ 객체끼리 λ³΅μ‚¬ν•˜λŠ” μš©λ„

// 볡사 λŒ€μž… μ—°μ‚°μž
	Person& operator=(const Person& p);

int main()
{
	Person player(30);
	Person enemy(15);

	Person addPlayer =  enemy;              // opeartor=() μ•ˆν–ˆλŠ”λ°λ„ μž˜λŒμ•„κ° -> μ™œ?
	addPlayer.introduce();


}

Person& Person::operator=(const Person& p)
{
	this->age = p.age;
	return *this;
}

 

 

 

< μ΄λ™μƒμ„±μž & 이동 λŒ€μž… μ—°μ‚°μž >

int main()
{
	Person player(30);
	Person enemy(15);

	Person copyPlayer(enemy);              
	Person movePlayer(std::move(player)); 
	// λŒμ•„κ°€κΈ΄ ν•˜λŠ”λ°
	// κΈ°μ‘΄ obj을 μ΄μš©ν•΄ μƒˆλ‘œμš΄ 것을 λ§Œλ“€ λ•Œ
	// copyκ°€ μ•„λ‹ˆλΌ moveν•΄μ„œ κ°€μ Έμ˜¬ 수 μžˆλ‹€

}


// 클래슀 λ‚΄λΆ€
// μ΄λ™μƒμ„±μž
	Person(Person&& other) noexcept : age(other.age)
	{	
		// 얕은 볡사
		other.age = 0;
		cout << "Person::Person() μ΄λ™μƒμ„±μž μ™„λ£Œ" << endl;
	}
    
// 이동 λŒ€μž… μ—°μ‚°μž
	Person& operator=(Person&& other) noexcept;
      
Person& Person::operator=(Person&& other) noexcept 
{
	this->age = other.age;
	other.age = 0;
	return *this;
}

// nocxcept : μ˜ˆμ™Έλ₯Ό 던질 κ°€λŠ₯μ„± μ—†μŒμ„ μ•Œλ¦Ό (false일 경우 μžˆλ‹€λŠ” 것)

 

 

 

 

< 동적할당 & 동적배열 >

// 클래슀 λ‚΄λΆ€
int setAge(int age) { return this->age = age; }

int main()
{
	Person* player = new Person(320);  // new -> μƒμ„±μž

	player->introduce();

	int n;
	cin >> n;
	Person* mon = new Person[n];
	for (int i = 0; i < n; i++) {
		mon[n].setAge(i + 1);
		mon[n].introduce();
	}

	delete player;  // delete -> μ†Œλ©Έμž
	delete[] mon;
}

 

 

 

< STRING의 class >

class STRING {
private:
	size_t num{}; //8
	char* p{};    //8

public:
	STRING();
	~STRING();
	STRING(const char* s);

	// λ³΅μ‚¬μƒμ„±μž(μŠ€νŽ˜μ…œ ν•¨μˆ˜)
	STRING(const STRING& other);

	STRING& operator=(const STRING& other);

	// μ΄λ™μƒμ„±μžμ™€ μ΄λ™ν• λ‹Ήμ—°μ‚°μž ( && - r-value reference, 이동(move)κ³Ό 완벽전달(perfect forwarding)에 μ‚¬μš©)
	STRING(STRING&& other);

	// μ—°μ‚°μž μ˜€λ²„λ‘œλ”©
	STRING operator+(const char*) const;
	STRING operator+(const STRING&) const;

	// μž…μΆœλ ₯κΈ°λŠ₯은 이 ν΄λž˜μŠ€μ™€ λ°€μ ‘ν•œ κΈ°λŠ₯이닀.
	// κ·Έλž˜μ„œ operator<< ν•¨μˆ˜λŠ” STRING의 멀버에 아직 이 ν•¨μˆ˜λ„ λ©€λ²„ν•¨μˆ˜μΈ 것 처럼 자유둭게
	// μ ‘κ·Όν•˜λ„λ‘ μ½”λ”©ν•˜λŠ” 것이 합리적이닀. -> 이 ν•¨μˆ˜λ₯Ό friend둜 μ„ μ–Έν•œλ‹€.

	friend std::ostream& operator<<(std::ostream&, const STRING&);
};
STRING::STRING() 
{

}

STRING::~STRING() 
{
	delete[]p;
}

STRING::STRING(const char* s) : num{ strlen(s) } 
{
	p = new char[num];
	memcpy(p, s, num);
}

// λ³΅μ‚¬μƒμ„±μž(μŠ€νŽ˜μ…œ ν•¨μˆ˜)
STRING::STRING(const STRING& other) : num(other.num) 
{
	p = new char[num];
	// deep copy
	memcpy(p, other.p, num);		// DMA;
}

STRING& STRING::operator=(const STRING& other) 
{
	// λ‚˜λ₯Ό λ‚˜λ‘œ ν• λ‹Ήν•  μ΄μœ κ°€ μ—†λ‹€
	if (this == &other)  // thisλŠ” μ£Όμ†ŒκΈ°μ— other도 μ£Όμ†Œ
		return *this;

	num = other.num;
	delete[] p;
	p = new char[num];
	memcpy(p, other.p, num);

	return *this;
}

// μ΄λ™μƒμ„±μžμ™€ μ΄λ™ν• λ‹Ήμ—°μ‚°μž ( && - r-value reference, 이동(move)κ³Ό 완벽전달(perfect forwarding)에 μ‚¬μš©)
STRING::STRING(STRING&& other) : num{ other.num } 
{

	// other의 μžμ›μ„ κ°€μ Έμ˜¨λ‹€
	p = other.p;
	// otherλ₯Ό μ΄ˆκΈ°ν™”
	other.num = 0;
	other.p = nullptr;
}

STRING STRING::operator + (const char* str) const {
	STRING temp;			// default ctor μŠ€νŽ˜μ…œ ν•¨μˆ˜

	temp.num = num + strlen(str);
	temp.p = new char(temp.num);

	memcpy(temp.p, p, num);
	memcpy(temp.p + num, str, strlen(str));

	return temp;			// μ—¬κΈ°μ„œ λ³΅μ‚¬μƒμ„±μžκ°€ ν˜ΈμΆœλ˜μ–΄μ•Ό ν•˜μ§€λ§Œ RVOκ°€ μž‘λ™λœλ‹€
	// RVO(Return Value Optimization) - λ°˜ν™˜κ°’ μ΅œμ ν™”
}

STRING STRING::operator+(const STRING& other) const {
	STRING temp;
	temp.num = num + other.num;
	temp.p = new char[temp.num];
	memcpy(temp.p, p, num);
	memcpy(temp.p + num, other.p, other.num);

	return temp;
}

std::ostream& operator<<(std::ostream& os, const STRING& s) 
{
	for (int i = 0; i < s.num; ++i)
		os << s.p[i];
	return os;
}

 

728x90