42seoul/projects

[CPP Module] 03

moaoh 2023. 7. 29. 22:17

ν•„μš”ν•œ κ°œλ…μ •λ¦¬

 

κΈ°λ³Έ κ·œμΉ™

Orthodox Canonical Form

module 02와 λ§ˆμΉœκ°€μ§€λ‘œ

  • μƒμ„±μž
  • 볡사 μƒμ„±μž
  • 볡사 ν• λ‹Ή μƒμ„±μž
  • μ†Œλ©Έμž

이 4κ°€μ§€λ₯Ό ν¬ν•¨ν•˜κ³  μžˆμ–΄μ•Όν•œλ‹€.

  • include guards
  • μ½”λ“œ 뢄할을 μœ„ν•΄ ν•„μš”ν•œ 경우 μΆ”κ°€νŒŒμΌ μ‚¬μš©κ°€λŠ₯
  • C++ μ—­μ‹œ newλ₯Ό μ‚¬μš©ν•˜λ©΄ λ©”λͺ¨λ¦¬ λˆ„μˆ˜κ°€ λ°œμƒλ  수 μžˆκΈ°λ•Œλ¬Έμ— λ©”λͺ¨λ¦¬μ— λŒ€ν•œ λˆ„μˆ˜λ°©μ§€λ₯Ό ν•΄μ€˜μ•Όν•œλ‹€

ex00

 

endl κ³Ό ‘\n’ 차이점

ex00에 듀어가기에 μ•žμ„œ κ°‘μžκΈ° endlκ³Ό '\n'의 차이가 κΆκΈˆν•΄μ Έμ„œ μ•Œμ•„λ³΄κ²Œλ˜μ—ˆλ‹€. κ·Έλž˜μ„œ μ•Œμ•„λ³΄λ‹ˆ

std::cout << "hello" << std::endl;

std::cout << "world" << '\n';

μœ„μ— 좜λ ₯λ˜λŠ” 두 λ¬Έμžμ—΄μ˜ 경우 좜λ ₯값은 μ„œλ‘œ λ˜‘κ°™μ΄ λ‚˜μ˜€κ²Œλœλ‹€. ν•˜μ§€λ§Œ λ‚΄λΆ€μ μœΌλ‘œ 보면 κΈ°λŠ₯적인 λΆ€λΆ„μ—μ„œ 차이점이 μƒκΈ°κ²Œ λ˜λŠ”λ°.

endl 같은 κ²½μš°μ—λŠ” ‘\n’κ³ΌλŠ” λ‹€λ₯΄κ²Œ 버퍼λ₯Ό λΉ„μš°λŠ” 역할을 같이 μ§„ν–‰ν•˜κ²Œ λœλ‹€.

좜처: TCP 슀쿨

λ¬Έμžμ—΄μ„ 좜λ ₯ν• λ•Œμ—λŠ” 일일이 λ°”λ‘œλ°”λ‘œ 좜λ ₯이 λ˜μ§€μ•Šκ³  λͺ¨μ™€λ‘μ—ˆλ‹€κ°€ λ²„νΌλΌλŠ” 것을 μ‚¬μš©ν•΄μ„œ ν•œλ²ˆμ— 좜λ ₯을 ν•˜κ²Œ λ˜λŠ”λ°

( 버퍼λ₯Ό μ‚¬μš©ν•˜μ§€μ•Šκ³  일일이 좜λ ₯을 ν•˜κ²Œλ˜λ©΄ 버퍼에 λͺ¨μ™€μ„œ 좜λ ₯ν•˜λŠ” 것보닀 느리게 좜λ ₯이 λœλ‹€. )

endl같은 κ²½μš°λŠ” newline + 버퍼λ₯Ό λΉ„μš°λŠ” 역할이 된 μ–˜λΌκ³  μƒκ°μ„ν•˜λ©΄ λœλ‹€.


ex01

기쑴에 λ§Œλ“€μ–΄λ‘μ—ˆλ˜ ClapTrap을 μƒμ†λ°›λŠ” ScavTrap을 μƒμ„±ν•΄μ•Όν•œλ‹€.

 

μƒμ†μ΄λž€.

class A
{
public:
	test();
}

class B : A
{
public:
	hi();
	// A클래슀λ₯Ό 상속받은 ν΄λž˜μŠ€μ΄κΈ°λ•Œλ¬Έμ— Aν΄λž˜μŠ€μ— μžˆλŠ” test도 Bν΄λž˜μŠ€μ—μ„œ μ‚¬μš©κ°€λŠ₯.
}

c++μ—μ„œμ˜ 상속은 기쑴에 클래슀(A)λ₯Ό μƒˆλ‘œμš΄ 클래슀(B)κ°€ 상속을 λ°›μ•„μ„œ A에 μžˆλŠ” 것듀을 μ‚¬μš©ν•  수 있게 λ˜λŠ” 것이 상속이라고 이야기λ₯Ό ν•œλ‹€.

μ ‘κ·Ό μ œν•œμž μ„€λͺ…

private 였직 μžμ‹ μ˜ ν΄λž˜μŠ€μ•ˆμ—μ„œλ§Œ μ ‘κ·Ό κ°€λŠ₯
protected μžμ‹ μ„ μƒμ†ν•˜λŠ” ν΄λž˜μŠ€κΉŒμ§€λ§Œ μ ‘κ·Ό κ°€λŠ₯
public μ–΄λ””μ„œλ“  μ ‘κ·Ό κ°€λŠ₯

μƒμ†μ—λŠ” μœ„μ™€κ°™μ΄ 총 3κ°€μ§€μ˜ μ ‘κ·Ό μ œν•œμžκ°€ μžˆλŠ”λ°.

( private < protected < public μˆœμ„œλ‘œ μ ‘κ·Ό λ²”μœ„κ°€ λ„“λ‹€. )

#include <iostream>

class A
{
private:
	int a;
protected:
	int b;
public:
	int c;
};

class B : public A
{
public:
	void sum() {
		a = 10; // NO : private error
		b = 20; // OK
		c = 30; // OK
	}
	void print() {
		std::cout << a; // NO : private error
		std::cout << b; // OK
		std::cout << c; // OK
	}
};

int main(void)
{
	B b;
	std::cout << b.a << std::endl; // NO : private error
	std::cout << b.b << std::endl; // NO : protected error
	std::cout << b.c << std::endl; // OK
	return (0);
}

클래슀λ₯Ό 상속받은 ν΄λž˜μŠ€λŠ” 기쑴의 ν΄λž˜μŠ€μ—μ„œ privateλ₯Ό μ œμ™Έν•œ λ‚˜λ¨Έμ§€ μ ‘κ·Ό μ œν•œμžλ“€μ„ μ‚¬μš©ν•  수 μžˆλ‹€.

class A
{
private:
	int a;
protected:
	int b;
public:
	int c;
};

class B : public A
{
// code
};

class C : protected A
{
// code
};

class D : private A
{
// code
};

μœ„μ™€ 같은 ν˜•μ‹μ²˜λŸΌ 상속을 받을 λ•Œ κ·Έλƒ₯ 상속을 λ°›λŠ”κ²ƒμ΄ μ•„λ‹ˆλΌ μ ‘κ·Ό μ§€μ •μžλ₯Ό μ§€μ •ν•΄μ„œ 상속을 받을 수 μžˆλŠ”λ° 해석을 ν•΄λ³΄μžλ©΄

  • class B : public A
    public 보닀 μ ‘κ·Ό λ²”μœ„κ°€ 넓은 것듀을 public 취급을 ν•˜κ² λ‹€λŠ” μ΄μ•ΌκΈ°μ΄μ§€λ§Œ public보닀 μ ‘κ·Ό λ²”μœ„κ°€ 넓은 것은 μ—†κΈ° λ•Œλ¬Έμ— μ ‘κ·Ό λ²”μœ„ κ·ΈλŒ€λ‘œ 상속을 λ°›κ² λ‹€λŠ” 의미
  • class C : protected A
    protected
    보닀 μ ‘κ·Ό λ²”μœ„κ°€ 넓은 것듀이 protected μ²˜λ¦¬κ°€ λœλ‹€ ( public )
  • class D : private A
    private
    보닀 μ ‘κ·Ό λ²”μœ„κ°€ 넓은 것듀이 private μ²˜λ¦¬κ°€ λœλ‹€ ( public, protected )

 

 

virtual (κ°€μƒν•¨μˆ˜)

κ°€μƒν•¨μˆ˜λž€

λΆ€λͺ¨ν΄λž˜μŠ€μ—μ„œ 상속받은 클래슀λ₯Ό μž¬μ •μ˜ 할것이라고 μ •μ˜ν•΄λ‘λŠ” ν•¨μˆ˜

class A
{
protected:
	int a;
public:
	virtual void print() {
		std::cout << "this is class A" << std::endl;
	}
};

class B : public A
{
public:
	void print() {
		std::cout << "this is class B" << std::endl;
	}
};

int main(void)
{
	A a;
	B b;
	a.print(); // this is class A
	b.print(); // this is calss B

	return (0);
}

μœ„μ™€ 같이 Aλ₯Ό 상속받은 B ν•¨μˆ˜μ—μ„œ 같은 맀개 ν•¨μˆ˜μ˜ λ‚΄μš©μ˜ 변경이 ν•„μš”ν•œ κ²½μš°μ—λŠ” virtual을 ν•¨μˆ˜ μ•žμ— λΆ™μ—¬
μž¬μ •μ˜ν•  ν•¨μˆ˜λΌκ³  λͺ…μ‹œλ₯Ό ν•΄μ£ΌλŠ” 방식이닀.

class A
{
public:
	A() {
		std::cout << "A Default constructor called" << std::endl;
	}
	~A() {
		std::cout << "A Destructor called" << std::endl;
	}
};

class B : public A
{
public:
	B() {
		std::cout << "B Default constructor called" << std::endl;
	}
	~B() {
		std::cout << "B Destructor called" << std::endl;
	}
};

int main(void)
{
	B b;

	return (0);
}

// print : A Default constructor called
//         B Default constructor called
//         B Destructor called
//         A Destructor called

μœ„μ™€ 같은 μ½”λ“œμ—μ„œ B의 κ²½μš°μ—λŠ” Aλ₯Ό μƒμ†λ°›μ•„μ„œ 생성이 된 μ½”λ“œμ΄κΈ°λ•Œλ¬Έμ— class Bλ₯Ό μƒμ„±ν•˜κ³  μ†Œλ©Έν•˜λŠ” κ³Όμ •μ—μ„œλŠ” A의 μƒμ„±μžμ™€ μ†Œλ©Έμžκ°€ λ‘˜ λ‹€ 싀행이 λœλ‹€.

μŠ€νƒμ˜ λ°©μ‹μ²˜λŸΌ μ„ μž…ν›„μΆœλ‘œ λΆ€λͺ¨ → μžμ‹μˆœμœΌλ‘œ 싀행이 되고 μ’…λ£Œκ°€ λ λ•ŒλŠ” μžμ‹ → λΆ€λͺ¨μˆœμœΌλ‘œ μ§„ν–‰μ΄λœλ‹€.

// 지정을 ν•΄μ€€ 경우 

class A
{
protected:
	std::string	name;
public:
	A() {
		std::cout << "A Default constructor called" << std::endl;
	}
	A(std::string name) {
		this->name = name;
		std::cout << name << " Default constructor called" << std::endl;
	}
	~A() {
		std::cout << "A Destructor called" << std::endl;
	}
};

class B : public A
{
public:
	B() {
		std::cout << "B Default constructor called" << std::endl;
	}
	B(std::string name) : A(name) {
		this->name = name;
		std::cout << name << " Default constructor called" << std::endl;
	}
	~B() {
		std::cout << "B Destructor called" << std::endl;
	}
};

int main(void)
{
	B b("Hi");

	return (0);
}

// print : Hi Default constructor called
//         Hi Default constructor called
//         B Destructor called
//         A Destructor called

νŠΉλ³„νžˆ 값을 λ°›λŠ” μƒμ„±μžμ˜ κ²½μš°μ—λŠ” μ–΄λ– ν•œ μƒμ„±μžλ₯Ό μƒμ†λ°›μ•„μ„œ 싀행을 ν•  것인지λ₯Ό λ”°λ‘œ μžμ‹ ν΄λž˜μŠ€μ—μ„œ 지정을 ν•΄μ€˜μ•Όν•œλ‹€. 이 μž‘μ—…μ„ ν•˜μ§€μ•ŠμœΌλ©΄ 상속을 받은 μžμ‹ ν΄λž˜μŠ€λŠ” λΆ€λͺ¨ 클래슀의 κΈ°λ³Έν˜•μ˜ μƒμ„±μžκ°€ 싀행이 λœλ‹€.

// 지정을 μ•ˆν•΄μ€€ 경우

class A
{
protected:
	std::string	name;
public:
	A() {
		std::cout << "A Default constructor called" << std::endl;
	}
	A(std::string name) {
		this->name = name;
		std::cout << name << " Default constructor called" << std::endl;
	}
	~A() {
		std::cout << "A Destructor called" << std::endl;
	}
};

class B : public A
{
public:
	B() {
		std::cout << "B Default constructor called" << std::endl;
	}
	B(std::string name) {
		this->name = name;
		std::cout << name << " Default constructor called" << std::endl;
	}
	~B() {
		std::cout << "B Destructor called" << std::endl;
	}
};

int main(void)
{
	B b("Hi");

	return (0);
}

// print : A Default constructor called
//         Hi Default constructor called
//         B Destructor called
//         A Destructor called

ex02

ex01와 μ΄ν•˜λ™λ¬Έ, ClapTrap을 μƒμ†λ°›λŠ” FragTrap을 μƒμ„±ν•΄μ•Όν•œλ‹€.

ex01κ³Ό λ‹€λ₯Έμ μ€ void attack( const std::string& target ); 을 κ°€μƒν•¨μˆ˜λ‘œ λ°›μ§€μ•Šκ³ ,
construction/destruction와 void highFivesGuys(void); λ₯Ό μƒμ„±ν•˜λ©΄ λœλ‹€.