๐Ÿ€ Knowledge/๊ฐ์ฒด์ง€ํ–ฅ์„ค๊ณ„

[๊ฐ์ฒด์ง€ํ–ฅ์„ค๊ณ„] ๊ฐ์ฒด ์ง€ํ–ฅ๊ณผ C++ ๊ธฐ๋ณธ

TIlearn 2023. 10. 22. 14:11

 

ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์„ธ๊ณ„์—์„œ ๊ฐ์ฒด ์ง€ํ–ฅ ์„ค๊ณ„๋Š” ๋ณต์žกํ•œ ๋ฌธ์ œ๋ฅผ ๋…ผ๋ฆฌ์ ์ด๊ณ  ํšจ์œจ์ ์œผ๋กœ ํ•ด๊ฒฐํ•˜๋Š”๋ฐ ๋„์›€์„ ์ฃผ๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํŒจ๋Ÿฌ๋‹ค์ž„ ์ค‘ ํ•˜๋‚˜์ด๋‹ค. ์ด์ œ๋ถ€ํ„ฐ, c++ ์–ธ์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด ์ง€ํ–ฅ ์„ค๊ณ„์— ๋Œ€ํ•ด ๊ณต๋ถ€ํ•ด ๋ณด๊ณ ์ž ํ•œ๋‹ค.

 

c++์€ ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์ง€์›ํ•˜๋Š” ๊ฐ•๋ ฅํ•œ ์–ธ์–ด๋กœ, ํด๋ž˜์Šค, ๊ฐ์ฒด, ์ƒ์†, ๋‹คํ˜•์„ฑ, ์บก์Аํ™”์™€ ๊ฐ™์€ ๊ฐœ๋…์„ ํšจ๊ณผ์ ์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค. ๋ฌผ๋ก , c++์„ ๊ณต๋ถ€ํ•˜๋Š”๋ฐ ์žˆ์–ด์„œ๋„ ๊ต‰์žฅํ•œ ๋„์›€์ด ๋  ๊ฒƒ์ด๋‹ค.

 

 

OOP์— ๋Œ€ํ•˜์—ฌ

 

OOP๋Š” ๊ฐ์ฒด ์ง€ํ–ฅ ์„ค๊ณ„์— ์žˆ์–ด ๋นผ๋†“์„ ์ˆ˜ ์—†๋Š” ๊ฐœ๋…์ด๋‹ค. ๋ฌด์กฐ๊ฑด ๋จธ๋ฆฌ์— ์ง‘์–ด๋„ฃ๋„๋ก ํ•˜์ž.

 

  • Class and Object(ํด๋ž˜์Šค, ๊ฐ์ฒด)
  • Abstraction(์ถ”์ƒํ™”)
  • Encapsulation(์บก์Аํ™”)
  • Inheritance(์ƒ์†)
  • Polymorphism(๋‹คํ˜•์„ฑ)

 

 

 

Class and Object

 

 

์‚ฌ์‹ค Class์™€ Object๋Š” ์–ด๋А์ •๋„ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ•ด๋ณด์•˜๋‹ค๋ฉด, ๋“ค์–ด๋ณธ ๋ฐ”๊ฐ€ ๊ฝค ์žˆ์„ ๊ฒƒ์ด๋‹ค. ํ”ํžˆ๋“ค ๋ถ•์–ด๋นต ํ‹€(class), ๋ถ•์–ด๋นต(object)๋ผ๊ณ  ๋น„์œ ํ•˜๊ธฐ๋„ ํ•˜๊ณ , ์„ค๊ณ„๋„์™€ ๊ฑด์ถ•๋ฌผ์ด๋ผ๊ณ  ๋น„์œ ํ•˜๊ธฐ๋„ ํ•œ๋‹ค. ์ฆ‰, ๊ทธ ๊ฐœ๋…์„ ์ธ์ง€ํ•˜๋Š”๋ฐ ์žˆ์–ด์„œ๋Š” ํฌ๊ฒŒ ์–ด๋ ต์ง€ ์•Š๋‹ค๋Š” ๋ง์ด๋‹ค.

 

๊ทธ๋ž˜๋„ ์กฐ๊ธˆ ๊ฐœ๋…์ ์œผ๋กœ ์„œ์ˆ ํ•˜์ž๋ฉด, Class๋Š” object์˜ ์ผ๋ฐ˜์ ์ธ ๊ตฌ์กฐ์ด๋ฉฐ object์˜ ๋ถ„๋ฅ˜๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ ์˜ˆ์‹œ๋กœ Car, Animal, Human ์ด๋Ÿฐ ๊ฒƒ๋“ค์ด class์ธ๋ฐ ์–ด๋– ํ•œ ๊ตฌ์ฒด์ ์ธ object, ๊ฐ€๋ น ๊ณ ์–‘์ด ๊ฐ™์€ object๋Š” Animal์ด๋ผ๋Š” class๋กœ ๋ถ„๋ฅ˜๋  ์ˆ˜ ์žˆ์ง€ ์•Š์€๊ฐ€.

 

์ด๋Ÿฌํ•œ class๋Š” properties์™€ behaviors๋กœ ๊ตฌ์„ฑ๋œ๋‹ค. ์ฆ‰, attibute์™€ methods๋กœ ๋ณผ ์ˆ˜๋„ ์žˆ๋‹ค. ์ด๋Š” ์†์„ฑ ๊ฐ’๊ณผ ์–ด๋–ค ํ–‰๋™ ์–‘์‹์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ์ง€ ๊ธฐ์ˆ ํ•œ ๊ฒƒ์ด๋‹ค.

 

Object๋Š” Class์˜ ์ธ์Šคํ„ด์Šค์ด๋‹ค. state์™€ Behavior์œผ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค. state๋Š” class์˜ properties์™€ ๊ด€๊ณ„๊ฐ€ ์žˆ์œผ๋ฉฐ, ํ˜„์žฌ object๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” properrties์ด๋‹ค. state๋Š” ๋ฐ”๋€” ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด ํŠน์ง•์ด๋‹ค.

 

behavior๋Š” object๊ฐ€ ํ•  ์ˆ˜ ์žˆ๋Š” actions์„ ๋œปํ•œ๋‹ค. ๋ณ„ ํŠน๋ณ„ํ•œ ์˜๋ฏธ๊ฐ€ ์žˆ๋‹ค๊ธฐ ๋ณด๋‹จ, ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” method๋ฅผ ๋งํ•˜๋Š” ๋“ฏ ์‹ถ๋‹ค.

 

 

 

 

์ถ”์ƒํ™”(Abstraction)

 

๊ตณ์ด ๊นŠ๊ฒŒ ํŒŒ๊ณ ๋“ค ํ•„์š”๊ฐ€ ์—†๊ฑฐ๋‚˜, ๊ด€๊ณ„ ๊ฐ€ ์—†๋Š” ๊ฒƒ๋“ค์€ ์ˆจ๊ธฐ๋Š” ๊ฒƒ์ด๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ์ž๋™์ฐจ ์—‘์…€์„ ๋ฐŸ์„ ๋•Œ ๊ตณ์ด ์—‘์…€ ๋ฐŸ์Œ์œผ๋กœ์จ ์ƒ๊ธฐ๋Š” ๋™์ž‘์›๋ฆฌ๋ฅผ ๊นŠ๊ฒŒ ์ดํ•ดํ•  ํ•„์š”๊ฐ€ ์—†๋Š” ๊ฒƒ๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€์ด๋‹ค. ์ฆ‰, ๊ตณ์ด ๋””ํ…Œ์ผํ•œ ์ดํ•ด ์—†์ด object๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ. ๊ทธ๊ฒƒ์ด ์ถ”์ƒํ™”์ด๋‹ค.

 

์ฝ”๋“œ์—์„œ ์šฐ๋ฆฌ๋Š” ์ด๋Ÿฌํ•œ ์ถ”์ƒํ™”๋ฅผ ์•Œ๊ฒŒ ๋ชจ๋ฅด๊ฒŒ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์„์ง€๋„ ๋ชจ๋ฅธ๋‹ค. class์•ˆ์— method๋ฅผ ๋งŒ๋“ค๊ณ , main ํ•จ์ˆ˜์—์„œ ๊ทธ method ๋‚ด์šฉ์„ ๊ตณ์ด ์ƒ๊ด€ ์“ฐ์ง€ ์•Š๊ณ , ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋„ ์ „๋ถ€ ์ถ”์ƒํ™”์˜ ์ผ์ข…์ด๋‹ค.

 

 

 

 

 

์บก์Аํ™”(Encapsulation)

 

์ธ๊ฐ€๋˜์ง€ ์•Š์€ ์–ด๋–ค ์ ‘๊ทผ์— ๋Œ€ํ•ด์„œ๋Š” ๋‚ด๋ถ€ ์ƒํƒœ(internal states)๋ฅผ ์ง€ํ‚ค๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค. ์ฆ‰, ์™ธ๋ถ€์—์„œ ๊ฑด๋“œ๋ฆฌ๋ฉด ์•ˆ๋˜๋Š” ๊ฒƒ๋“ค์— ๋Œ€ํ•ด์„œ๋Š” ์บก์А์„ ์”Œ์›Œ ๋ฐ–์—์„œ ๊ฑด๋“œ๋ฆฌ์ง€ ๋ชปํ•˜๋„๋ก ํ•ด์•ผํ•œ๋‹ค๋Š” ๋ง์ด๋‹ค. ์ฝ”๋“œ์—์„œ๋Š” ์˜ค์ง class๊ฐ€ ์ œ๊ณตํ•ด์ฃผ๋Š” interface๋ฅผ ํ†ตํ•ด์„œ๋งŒ state๊ฐ€ ๋ณ€ํ•˜๋Š” ๊ฒƒ์„ ํ—ˆ์šฉํ•ด ์ฃผ์–ด์•ผ ํ•œ๋‹ค. ์ฝ”๋“œ์—์„œ ์ด๋Š” private๊ฐ™์€ ๊ฒƒ์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

 

 

 

์ƒ์†(Inheritance)

 

์ƒ์†์€ ๊ต‰์žฅํžˆ ์•Œ์•„์•ผ ํ•  ๊ฒƒ์ด ๋งŽ๋‹ค. ์ด ๋˜ํ•œ ์ดํ›„์— ์•Œ์•„๊ฐ€๊ธฐ๋กœ ํ•˜๊ณ , ๊ธฐ๋ณธ์ ์ธ ๊ฐœ๋…๋งŒ ์ˆ™์ง€ํ•˜์ž.

์ƒ์†์€ ๋ถ€๋ชจ ํด๋ž˜์Šค๋ฅผ ํ•˜์œ„ ์ž์‹ ํด๋ž˜์Šค๋กœ attibute์™€ methods๋ฅผ ๋„˜๊ฒจ์ฃผ๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค. ์ด๋Š” ์—ฌ๋Ÿฌ ์กฐ๊ฑด์— ์˜ํ•ด ๋„˜๊ฒจ์ง€๋Š” ๊ฒƒ๋„ ์žˆ๊ณ , ์กฐ๊ธˆ ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ๋„ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ถ„๋ช…ํ•œ ๊ฒƒ์€ ๊ทธ ํด๋ž˜์Šค๋“ค๊ด€์˜ ๊ด€๊ณ„๋Š” ๋ถ€๋ชจ/์ž์‹ ๊ด€๊ณ„๋ผ๋Š” ๊ฒƒ์ด๋‹ค.

 

์ด๋ฅผ super class(์ž์‹) / sub class(๋ถ€๋ชจ), child class(์ž์‹) / parent class(๋ถ€๋ชจ), derived class(์ž์‹) / base class(๋ถ€๋ชจ)๋กœ ๋งคํ•‘ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์ž์‹์€ ๋ถ€๋ชจ์˜ ๊ธฐ๋Šฅ์„ ๋ฌผ๋Ÿฌ ๋ฐ›์•„ ๊ทธ ์ด์ƒ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๊ธฐ์–ตํ•˜์ž.

 

 

 

 

๋‹คํ˜•์„ฑ(Polymophism)

 

๋‹คํ˜•์„ฑ์€ ๊ฝค ์ค‘์š”ํ•˜๋‹ค. ๋˜ ์ƒ์†์ด๋ผ๋Š” ๊ฒƒ๋„ ์‚ฌ์‹ค ํ•˜๋‚˜์˜ ๋‹คํ˜•์„ฑ์„ ์ง€์›ํ•˜๋Š” ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜์ด๊ธฐ๋„ ํ•˜๋‹ค.

 

๋‹คํ˜•์„ฑ์€ ๊ฐ์ฒด์˜ ๋‹ค์–‘ํ•œ ํ˜•ํƒœ๋‚˜ ํƒ€์ž…์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ๋Šฅ๋ ฅ์„ ๋งํ•œ๋‹ค. ์ฆ‰, ์ƒ์†๋„ ๋ถ€๋ชจ ํด๋ž˜์Šค๊ฐ€ ํ•˜์œ„ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ํฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์ƒ๊ฐํ•ด๋ณด์ž. ํ—ท๊ฐˆ๋ฆฌ๋ฉด ์•ˆ๋˜๋Š” ๊ฒƒ์ด ๋‹คํ˜•์„ฑ์€ ๋” ๋„“์€ ๋ฒ”์œ„๋ฅผ ํฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด ๋” ํฌ๋‹ค๊ณ  ๋ณด์•„์•ผ ํ•œ๋‹ค.

 

๊ฐ€๋ น, ์ฐจ๋Š” ๋ฒ„์Šค๊ฐ€ ๋  ์ˆ˜ ์žˆ์ง€๋งŒ ๋ฒ„์Šค๋Š” ์ฐจ๊ฐ€ ๋  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฑธ๋กœ ์ดํ•ดํ•ด๋ณด์ž. ์•„๋ฌดํŠผ, ์ด๋Ÿฌํ•œ ๋‹คํ˜•์„ฑ์€ ๋‘๊ฐ€์ง€ ์ข…๋ฅ˜๋กœ ๋‚˜๋‰œ๋‹ค.

 

  • Static polymorphism
    • ์ด๋Š” ์ปดํŒŒ์ผ ์ด์ „์—์„œ ์ปดํŒŒ์ผ๊นŒ์ง€๊ฐ€ ๋ฒ”์œ„์ด๋‹ค.
    • Method overloading
    • Method overriding
  • Dynamic polymorphism
    • ์ด๋Š” ๋Ÿฐํƒ€์ž„ ์‹œ๊ฐ€ ๋ฒ”์œ„์ด๋‹ค.
    • Virtual function calls

 

 

ํ•ด๋‹น ๋‘๊ฐ€์ง€ ๊ฒฝ์šฐ์™€ ์–ด๋–ค ์‹œ๊ธฐ์— ์‹คํ–‰๋˜๋Š” ์ง€ ์ œ๋Œ€๋กœ ํŒŒ์•…ํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค.

 

 

 

 

Class์™€  Constuctor, Namespace

 

 

 

Class ์„ ์–ธ

 

class Door {
};

class Car {
	public:
		Car(std::string name) : name_(name) {}
		std::string name() { return name_; }
		Door getDoor(int index) { return doors_[index]; }
        
 	private:
		std::string name_;
		Door doors_[4];
}

 

Class์˜ ์„ ์–ธ ๋ฐฉ๋ฒ•์€ ์–ด๋ ต์ง€ ์•Š๋‹ค. ๋‹ค๋ฅธ ์–ธ์–ด์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ class name { ... } ๋กœ ์“ฐ๋ฉด ๋œ๋‹ค.

 

 

 

Object ์ƒ์„ฑ

 

์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์—ฌ๋Ÿฌ๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.

 

  • Direct initialization
    • Car car("mycar")
      • "์•”๋ฌต์ "์œผ๋กœ Car class์˜ constructor๋ฅผ ๋ถ€๋ฅธ๋‹ค.
    • Car car = Car("mycar")
      • "๋ช…์‹œ์ "์œผ๋กœ Car class์˜ constructor๋ฅผ ๋ถ€๋ฅธ๋‹ค.
  • Conversion
    • Car car = std::string("mycar")
      • ์•”๋ฌต์ ์œผ๋กœ, string value๋ฅผ class Car์˜ object๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.
    • Car car = (Car) "mycar"
      • ๋ช…์‹œ์ ์œผ๋กœ, string value๋ฅผ class Car์˜ object๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.

 

๊ทผ๋ฐ, ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๋ช…์‹œ์ ์œผ๋กœ constructor๋ฅผ ๋ถ€๋ฅด๋Š” Car car = Car("mycar")๋ฅผ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค.

 

 

 

์ ‘๊ทผ ์ œ์–ด์ž

 

Private, Protected, Public์œผ๋กœ ๋‚˜๋‰œ๋‹ค.

 

  • Private
    • ํด๋ž˜์Šค ๋‚ด๋ถ€์—์„œ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๋‹ค.
  • Protected
    • class ๋‚ด๋ถ€์ด๊ฑฐ๋‚˜, ์ƒ์† ๋ฐ›์€ class ๋‚ด๋ถ€์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • Public
    • ์–ด๋””์—์„œ๋‚˜ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

 

 

Constructor

 

์•„๋ž˜์™€ ๊ฐ™์ด ์ƒ์„ฑ์ž๋ฅผ ์„ ์–ธํ•ด ์ค„ ์ˆ˜ ์žˆ๋‹ค.

name(parameter*) : (, member-field(expression*))* { body-statement }

 

๋˜ํ•œ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋Š” constructor๋กœ๋Š” ๋ช‡๊ฐ€์ง€ ์ข…๋ฅ˜๊ฐ€ ์žˆ๋‹ค.

 

1. Default Contructor

 

parameter๋ฅผ ๊ฐ€์ง€์ง€ ์•Š๋Š” ์ƒ์„ฑ์ž์ด๋‹ค. ํ˜น์€ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์žˆ์–ด๋„ ๊ธฐ๋ณธ ๊ฐ’์ด ์ง€์ •๋œ ์ƒ์„ฑ์ž๋ฅผ ๋งํ•œ๋‹ค.

์ด ์ƒ์„ฑ์ž๋Š” Compiler๊ฐ€ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•œ๋‹ค. ๋‹จ, ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ์ •์˜ํ•œ ์ƒ์„ฑ์ž๊ฐ€ ์—†์„ ๋•Œ๋งŒ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

์•”๋ฌต์ ์œผ๋กœ ๋ชจ๋“  ๋ฉค๋ฒ„ ํ•„๋“œ์— ๋Œ€ํ•ด default constructor๋ฅผ ๋ถ€๋ฅธ๋‹ค. ๋งŒ์•ฝ์— ๋ฉค๋ฒ„ ํ•„๋“œ์— ๋Œ€ํ•ด์„œ ์•„๋ฌด๋Ÿฐ default constructor๊ฐ€ ์—†๋‹ค๋ฉด, Compiler๋Š” ์—๋Ÿฌ๋ฅผ ๋‚ด๋†“๋Š”๋‹ค.

 

// default constructor๊ฐ€ ์ƒ์„ฑ ๋ชปํ•จ
class Door {
    public:
        Door(std::string color) : color(color) {} // User-defined constructor with one parameter
    private:
        std::string color;
};

class Car {
     public:
         // Car() : name("mycar") { } // Default constructor
         // std::string name() { return name; }
     private:
         std::string name;
         Door doors; // Error: no matching function for call to 'Door::Door()'
};
 
int main() {
    Car car1; // Error: no matching function for call to 'Door::Door()'

    return 1;
}

 

2. Implicit Conversion constructor

 

์ƒ์„ฑ์ž๊ฐ€ ์ ์–ด๋„ ํ•˜๋‚˜์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์žˆ๊ณ , explicit ์ด๋ผ๋Š” ํ‚ค์›Œ๋“œ๊ฐ€ ์•ž์— ๋ถ™์ง€ ์•Š์€ constructor๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

์ด ์ƒ์„ฑ์ž์˜ ์—ญํ• ์€ ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฐ’์˜ ํƒ€์ž…์ด class์˜ object๋กœ ๋ณ€ํ™˜๋˜๊ฒŒ ํ•ด์ค€๋‹ค. c++11 ๋ฒ„์ „์ดํ›„๋กœ, ์ด ์ƒ์„ฑ์ž์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์•„๋ฌด๊ฒƒ๋„ ์—†๊ฑฐ๋‚˜ ๊ทธ ์ด์ƒ์˜ ๊ฐ’์ด ๋˜์–ด๋„ ์•„๋ฌด๋Ÿฐ ์ƒ๊ด€์ด ์—†์–ด์กŒ๋‹ค. ์ด๋Š” explicit์ด๋ผ๋Š” ํ‚ค์›Œ๋“œ๊ฐ€ ์ง€์ •๋˜์ง€ ์•Š์€ constructor๊ฐ€ implicit conversion constructor๋ผ๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜๊ธฐ๋„ ํ•œ๋‹ค.

 

Google C++ style guide๋Š” ๊ตณ์ด ์ด๋Ÿฌํ•œ type constructor๋ฅผ ์“ฐ์ง€ ์•Š๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•œ๋‹ค.

 

class Car {
    public:
        Car(std::string name) : name_(name) { } // Implicit converting constructor
        ...
}

int main() {
    Car car1("mycar");
    Car car2 = Car("mycar");
    Car car3 = "mycar"s;
    Car car4 = (Car) "mycar";
}

 

 

3. Explicit conversion constructor

 

์˜ค์ง ํ•˜๋‚˜์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๊ฐ€์ง€๋ฉฐ, explicit ์ด๋ผ๋Š” ํ‚ค์›Œ๋“œ๋กœ ๊ตฌ์„ฑ๋œ constructor์ด๋‹ค.

์ด constructor๋Š” ์œ„์˜ Implicit conversion๊ณผ ๋‹ฌ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ ํƒ€์ž…์ด class์˜ object๋กœ ๋ณ€ํ™˜ํ•˜์ง€ ๋ชปํ•˜๋„๋ก ํ•œ๋‹ค.

 

Google C++ style guide๋Š” ๋ชจ๋“  constructor๊ฐ€ explicit conversion constructor๋กœ ์ •์˜ํ•˜๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•œ๋‹ค.

 

 

class Car {
    public:
        explicit Car(std::string name) : name_(name) { }
        
    private:
        std::string name_;
        Door doors[4]
};

int main() {
    Car car1("mycar");
    Car car2 = Car("mycar");
    Car car3 = "mycar"s; // ์ด๊ฑด ์ž๋™์œผ๋กœ ํƒ€์ž… ๋ณ€ํ™˜์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.
    Car car4 = (Car) "mycar";
}

 

 

3. Copy constructor

 

object๋ฅผ copyํ•˜๊ธฐ ์œ„ํ•œ consructor์ด๋‹ค. ์ด๋Š” ๋ณต์‚ฌํ•˜๋ ค๋Š” object์˜ ๋ชจ๋“  ๋ฉค๋ฒ„ ํ•„๋“œ ๊ฐ’์„ ๋ณต์‚ฌํ•˜์—ฌ ์ง‘์–ด๋„ฃ๋Š”๋‹ค.

๋˜ํ•œ ๋ชจ๋“  ๋ฉค๋ฒ„ ํ•„๋“œ์— ๋Œ€ํ•ด์„œ shallow copy๋ฅผ ์ง„ํ–‰ํ•œ๋‹ค. ๋งŒ์•ฝ shallow copy๊ฐ€ ์•„๋‹Œ deep copy๋ฅผ ์›ํ•œ๋‹ค๋ฉด, ๋”ฐ๋กœ ๋งŒ๋“ค์–ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

 

์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ๋ณด๋ฉด, ์ƒ์„ฑ์ž์— ์ง์ ‘์ ์œผ๋กœ Explicit์ด ๋ถ™์–ด ์žˆ์ง€ ์•Š๋‹ค. ์ฆ‰, ์ƒ์„ฑ์ž ํ˜ธ์ถœ ์‹œ Implicit ํ˜น์€ Explicitํ•˜๊ฒŒ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์„ ํ—ˆ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค.

 

๋ฐ˜๋ฉด, ์ƒ์„ฑ์ž์— Explicit์ด ๋ถ™์–ด์žˆ๋‹ค๋ฉด, Implicit ํ˜ธ์ถœ์€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋ฉฐ, ์˜ค์ง Explicit์„ ํ†ตํ•ด ํ˜ธ์ถœํ•˜์—ฌ์•ผ ํ•œ๋‹ค.

class Car {
    public:
        Car() : name_("mycar") {}
        Car(const Car& car) : name_(car.name_) {
            for(int i=0; i<4; ++i) {
                doors_[i] = car.doors_[i];
            }
        }
    private:
        std::string name_;
        Door doors_[4];
};

int main() {
    Car car;
    Car car2(car); // Implicit copy constructor call
    Car car3 = Car(car2); // Explicit copy constructor call
    Car car4 = car3;
}

 

 

์–•์€ ๋ณต์‚ฌ(Shallow copy) : ์›๋ณธ ๊ฐ์ฒด์™€ ๋ณต์‚ฌํ•œ ๊ฐ์ฒด๊ฐ€ ์„œ๋กœ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๊ฒƒ. ์ฆ‰, ํฌ์ธํ„ฐ๊ฐ€ 
๊นŠ์€ ๋ณต์‚ฌ(Deep copy) : ์›๋ณธ ๊ฐ์ฒด์™€ ๋ณต์‚ฌํ•œ ๊ฐ์ฒด๊ฐ€ ์™„์ „ํžˆ ๋…๋ฆฝ์ ์ธ ๋ฐ์ดํ„ฐ ์ฐธ์กฐ๋ฅผ ๊ฐ€์ง€๋Š” ๊ฒƒ.


์ฆ‰, ์–•์€ ๋ณต์‚ฌ๋Š” ํฌ์ธํ„ฐ๊ฐ€ ๊ฐ™์€ ๊ฑฐ๊ณ , ๊นŠ์€ ๋ณต์‚ฌ๋Š” ๊ฐ’๋งŒ ๋ณต์‚ฌํ•˜๊ณ  ํฌ์ธํ„ฐ๊ฐ€ ๋‹ค๋ฅธ๋‹ค๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

C++์˜ Class์—์„œ ์นœ๊ตฌ ๊ด€๊ณ„(Friends)

 

C++์—์„œ๋Š” friends๋ผ๋Š” ๊ด€๊ณ„๋ฅผ Class๋‚ด์—์„œ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ง๋งŒ ์นœ๊ตฌ์ง€ ์‚ฌ์‹ค ์ƒ ๋‚˜๋งŒ ์นœ๊ตฌ๋กœ ์ƒ๊ฐํ•˜๋Š” ์ผ๋ฐฉ์ ์ธ ์นœ๊ตฌ ๊ด€๊ณ„์ด๋‹ค. ๋‚ด๊ฐ€ ์นœ๊ตฌ๋กœ ์ƒ๊ฐํ•˜๋Š” ๋Œ€์ƒ class์—์„œ๋Š” ๋‚˜์˜ ๊ธฐ๋Šฅ์„ ์ „๋ถ€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋‚˜, ๋‚˜๋Š” ๋Œ€์ƒ class์˜ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค. ์ข€ ํ˜ธ๊ตฌ๊ฐ™์€ ๊ด€๊ณ„์ด๋‹ค.

 

class Person {
    public:
        void CallCat() {
            cat_ -> Move(); // Error๊ฐ€ ๋‚œ๋‹ค.
        }
        
    private:
        Hand hands_[2];
        Leg legs_[2];
        Cat* cat_;
        friend Cat; // ๋‚˜๋งŒ ์นœ๊ตฌ์ธ ๊ด€๊ณ„
}

 

 

class Cat {
    public:
        void TouchHuman() {
        	// ๋‚  ์นœ๊ตฌ๋กœ ์ƒ๊ฐํ•˜๋Š” ์นœ๊ตฌ์˜ ๊ฒƒ์€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ.
            Hand left_hand = owner_ -> hands_[0];
            Leg right_hand = owner_ -> legs_[0];
        }
        
    private:
        Leg legs_[4];
        Person* owner;
        void Move() { ... }
}

 

 

 

 

 

C++์—์„œ์˜ ์„ ์–ธ๊ณผ ์ •์˜

 

 

Class์—์„œ์˜ ํ•จ์ˆ˜์˜ ์„ ์–ธ

 

private๋กœ ์ง€์ •๋œ ๋ฉค๋ฒ„ ํ•„๋“œ์— ๋Œ€ํ•œ ์กฐ์ž‘์„ ์œ„ํ•ด ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•ด ์ค„ ์ˆ˜๋„ ์žˆ๋‹ค. ํฌ๊ฒŒ ์–ด๋ ค์šด ๊ฒƒ์€ ์—†๊ณ  ๊ฐ„๋‹จํ•˜๊ฒŒ Return ํƒ€์ž…๊ณผ ํ•จ์ˆ˜ ์ด๋ฆ„, ๊ทธ๋ฆฌ๊ณ  ํŒŒ๋ผ๋ฏธํ„ฐ ์ •๋ณด๋งŒ ์ž‘์„ฑํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

 

 

class Car {
    public:
        Car(std::string name);
        void set_name(std::string name);
        std::string name();
        
    public:
        std::string name_;
}

 

 

Class์—์„œ์˜ ํ•จ์ˆ˜์˜ ์ •์˜

 

์•ž์„  class์— ๋Œ€ํ•œ ์„ ์–ธํŒŒ์ผ์€ .h ํŒŒ์ผ์—์„œ ์ž‘์„ฑํ•œ๋‹ค. ์‹ค์งˆ์ ์œผ๋กœ ์ž‘๋™ ๊ณผ์ •์— ๋Œ€ํ•œ ๋ถ€๋ถ„์€ .cc ํŒŒ์ผ ํ˜น์€ .cpp์—์„œ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค. ์•ž์„ , ์ •์˜์™€ ๊ตฌ์กฐ๊ฐ€ ๋™์ผํ•˜๋„๋ก ์ž‘์„ฑํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

 

ReturnType className::FunctionName(parameters { Body statement; }

 

์ฆ‰, ์œ„์™€ ๊ฐ™์ด clasName๊ณผ "::" ๋ฅผ ํ†ตํ•ด์„œ ๊ทธ class์— ์ •์˜๋œ Function ๋‚ด์šฉ์„ ์ž‘์„ฑํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

์กฐ๊ธˆ ๊ธฐ์–ตํ•ด์•ผ ํ•  ๊ฒƒ์€ h ํŒŒ์ผ ๋‚ด์—์„œ include ์‹œํ‚จ ๋‚ด์šฉ์— ๋Œ€ํ•ด์„œ๋Š” ๊ตณ์ด h ํŒŒ์ผ์„ ํฌํ•จ ์‹œํ‚จ cc ํŒŒ์ผ ๋‚ด์—์„œ ๋‹ค์‹œ ์ž‘์„ฑํ•  ํ•„์š”๋Š” ์—†๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋ ‡๋“ฏ, h ํŒŒ์ผ๊ณผ cc ํŒŒ์ผ์„ ๋‚˜๋ˆ„๋Š” ์ด์œ ๋Š” ๋ชจ๋“ˆํ™”์™€ ์œ ์ง€๋ณด์ˆ˜ ์ธก๋ฉด์—์„œ ์œ ๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

 

์ฆ‰, ์•„๋ž˜์™€ ๊ฐ™์ด cc ํŒŒ์ผ์—์„œ h ํŒŒ์ผ์„ ํฌํ•จ ์‹œ์ผœ์ค€๋‹ค.

 

#include <iostream>
#include "car.h"

int main() {
    Car car("mycar");
    std::cout << car.name() << std::endl;
    return 1;
}

 

 

 

 

 

 

Class์—์„œ์˜ ์ข‹์€ Pratice

 

 

  • Class์˜ ์ด๋ฆ„์€ Pascal cases์ด๋‹ค.
class Cat { ... };
class Person { ... };
class ChungnamUniv { ... };

 

์–ด๋А ๊ณณ์— ๊ฐ€๋“ , ์ฝ”๋“œ ์ปจ๋ฒค์…˜์€ ์ง€ํ‚ค๋Š” ๊ฒƒ์ด ์‹ ์ƒ์— ์ข‹๋‹ค. C++์—์„œ class์˜ ์ด๋ฆ„์€ Pascal Case๋กœ ์ž‘์„ฑํ•ด์ฃผ์ž.

 

  • ์˜ค์ง ๋ฉค๋ฒ„ ํ•„๋“œ์— ๋Œ€ํ•œ public access๋งŒ์„ ๊ฐ€์ง€๋Š” ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์—์„œ๋Š” clsss ๋Œ€์‹ ์— struct๋ฅผ ์‚ฌ์šฉํ•˜์ž.
struct Point {
    int x_;
    int y_;
}

 

์‚ฌ์‹ค ๋™์ž‘ ์ž์ฒด๋Š” Class๋‚˜ Struct๋‚˜ ๋™์ผํ•˜์ง€๋งŒ, publicํ•œ ์ ‘๊ทผ๋งŒ์„ ๊ฐ€์ง€๋Š” ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ผ๋ฉด struct๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

 

 

  • ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋Š” snake_case์ด๋ฉฐ, ๋งˆ์ง€๋ง‰์—๋Š” _(underscore)๋ฅผ ๋ถ™์—ฌ์ค€๋‹ค.
class Person {
    int age_;
    std::string home_address_;
};

์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š” local์— ์žˆ๋Š” ๋ณ€์ˆ˜์™€ member ๋ณ€์ˆ˜ ๊ฐ„์˜ ๊ตฌ๋ถ„์„ ์œ„ํ•ด์„œ์ด๋‹ค.

 

 

  • ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋Š” Upper-Carmel-Case๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

์‚ฌ์‹ค ์ƒ Pascal๊ณผ ๋™์ผํ•˜๊ฒŒ ์ž‘์„ฑํ•œ๋‹ค. ๊ธฐ์–ตํ•  ๋งŒํ•œ ์ฐจ์ด์ ์ด ์žˆ๋‹ค๋ฉด, ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์— ๋Œ€ํ•œ getter ํ•จ์ˆ˜๊ฐ€ ์žˆ์„ ๋•Œ๋Š” ๊ทธ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์˜ ์ผ๋ฆ„๊ณผ ๋™์ผํ•˜๊ฒŒ ํ•จ์ˆ˜ ์ด๋ฆ„์„ ์ž‘์„ฑํ•ด์ค€๋‹ค.

class Person {
    int DoSomthing() { ... }
    int age() { return age_; }
    int age_;
};

 

 

  • ๋ฉค๋ฒ„ ํ•„๋“œ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ, ์ ‘๊ทผ ์ œ์–ด์ž๋Š” public์—์„œ private ์ˆœ์œผ๋กœ ์ž‘์„ฑํ•˜๋„๋ก ํ•œ๋‹ค.

 

class Person {
    public:
        int age() { return age_; }
        int DoSomething1() { ... }
        
    protected:
        int DoSomething2() { ... }
    
    private:
        int age_;
        std::string home_address_;
}

 

 

 

  • ๋‹น์—ฐํ•˜์ง€๋งŒ, ์„ ์–ธ๊ณผ ์ •์˜์— ๋Œ€ํ•œ ํŒŒ์ผ์€ ๋‚˜๋ˆ„์–ด ๋†“์ž.(์ฆ‰, ccํŒŒ์ผ๊ณผ hํŒŒ์ผ์„ ๊ตฌ๋ถ„ํ•˜์—ฌ ๋‘์ž.)

 

  • ๋ชจ๋“  constructor๋Š” Explicitํ•˜๊ฒŒ ์ž‘์„ฑํ•˜์ž.

์•ž์„œ ๋ฐฐ์› ๋“ฏ, implicit์€ ํƒ€์ž…์— ๋Œ€ํ•œ conversion์ด ์ž๋™์œผ๋กœ ์ด๋ฃจ์–ด์ง€์ง€๋งŒ, Explicit์€ ๊ทธ๊ฒƒ์„ ์ œํ•œํ•œ๋‹ค. ์–ธ๋œป๋ณด๋ฉด ํŽธํ•œ๊ฒƒ ์•„๋‹Œ๊ฐ€ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๋Š” ์น˜๋ฉด์ ์ธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์˜ค๋ฅ˜๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ด์œ ๋กœ ์ธํ•ด ์™ ๋งŒํ•˜๋ฉด constructor๋Š” Explicitํ•˜๊ฒŒ ์ž‘์„ฑํ•˜์ž.

 

 

Class Person {
    public:
        explicit Person(int age);
        explicit Person(int age, std::string addr);
    
    private:
        int age_;
        std::string home_address_;
}

// Person p(3)์œผ๋กœ ํ•˜๋ฉด, int ๊ฐ’์ด ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฐ’์œผ๋กœ ๋“ค์–ด์˜ด์ด ๋ช…๋ฐฑํ•˜๋‹ค.
// Person p = 3์€ ์•”๋ฌต์ ์œผ๋กœ ํƒ€์ž…์„ ๋ณ€ํ™˜ํ•˜์—ฌ object๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

 

object๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์— ์žˆ์–ด ํ—ท๊ฐˆ๋ฆฐ๋‹ค๋ฉด ์•ž์„œ ๋ฐฐ์šด object ์ƒ์„ฑ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๋‹ค์‹œํ•œ๋ฒˆ ๋ณด๊ณ  ์˜ค๊ธธ ๋ฐ”๋ž€๋‹ค.

 

 

 

Namespace

 

 

namespace๋Š” ํ•จ์ˆ˜, ๋ณ€์ˆ˜, class๋“ค์„ ํฌํ•จํ•˜๋Š” ํŠน์ˆ˜ํ•œ ์ฝ”๋“œ ์˜์—ญ์ด๋‹ค. C++ ๋‚ด์—์„œ๋Š” ๊ฐ™์€ ์‹๋ณ„์ž๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์—†์ง€๋งŒ ์ด namespace๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๊ฐ€๋Šฅํ•ด์ง„๋‹ค.

 

ํ•˜์ง€๋งŒ, ๊ฐ™์€ namespace ์•ˆ์—์„œ๋Š” ์‹๋ณ„์ž๊ฐ€ ์ค‘๋ณต๋˜๋ฉด ์•ˆ๋œ๋‹ค. ๋˜ํ•œ main function์€ ๋‹ค๋ฅธ namespaces์— ์†ํ•  ์ˆ˜ ์—†๋‹ค.

 

 

 

#include <iostream>

namespace ns1 {
    int value = 3;
}

namespace ns2 {
    std::string value("Hi there");
}

int main() {
    std::cout << ns1::value << std::endl;
    std::cout << ns2::value << std::endl;
}

 

 

 

Nested namespace

 

namespace์•ˆ์—๋Š” ์—ฌ๋Ÿฌ namespace๋ฅผ ์ค‘์ฒฉ๋œ ๊ตฌ์กฐ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์—ญ์‹œ๋‚˜, ๊ฐ™์€ ์‹๋ณ„์ž์˜ ๋ณ€์ˆ˜๋ฅผ ๋™์‹œ์— ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

#include <iostream>

namespace ns1 {
    void foo() {
        std::cout << "foo() in ns1" << std::endl;
    }
    
    namespace ns2() {
        void foo() {
            std::cout << "foo() in ns2" << std::endl;
        }
        
        namespace ns3() {
            void foo() {
                std::cout << "foo() in ns3" << std::endl;
            }
        }
    }
    
    namespace ns4() {
        void foo() {
            std::cout << "foo() in ns3" << std::endl;
        }
    }
}

int main() {
  ns1::foo();
  ns1::ns2::foo();
  ns1::ns2::ns3::foo();
  ns1::ns4::foo();
}

๋˜ํ•œ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ด๋ ‡๊ฒŒ nested๋˜๊ฒŒ ์ž‘์„ฑ๋œ namespace์•ˆ์—์„œ ์‹๋ณ„์ž๋ฅผ ์ฐพ์„ ๋•Œ๋Š” ์•ˆ์—์„œ ๋ถ€ํ„ฐ ๋ฐ–์œผ๋กœ ์ฐพ๋Š”๋‹ค.

 

 

๊ฐ™์€ namespace์˜ ๋ถ„๋ฆฌ๋œ ์ž‘์„ฑ

 

์•„๋ž˜์™€ ๊ฐ™์ด namespace๋ฅผ ์“ธ ๋•Œ ๊ตณ์ด ํ•œ๋ฒˆ์— ๋‹ค์“ฐ์ง€ ์•Š์•„๋„ ์ข‹๋‹ค.

namespace ns1 {
    void foo() {
        std::cout << "foo() in ns1" << std::end;
    }
}

namespace ns1 {
    void bar() {
        std::cout << "bar() in ns1" << std::end;
    }
}

int main() {
    ns1::foo();
    ns1::bar();
    return 0;
}

 

 

namespace์—์„œ์˜ ์ข‹์€ Pratice

 

  • namespace๋Š” snake-cases ์ž‘์„ฑํ•œ๋‹ค.
namespace theory { ... }
namespace object_oriented { ... }
namespace good_practice_in { ... }

 

 

 

  • ์–ด๋–ค namespace์ธ์ง€์— ๋Œ€ํ•œ comment๋ฅผ ๋ช…๋ฐฑํžˆ ๋‚จ๊ฒจ์•ผ ํ•œ๋‹ค.
namespace object_oriented {
    namespace good_pratice_in{
        ...
    } // namespace good_pratice_in
} // namespace object_oriented

 

  • "using namespace::์‚ฌ์šฉํ•˜๊ณ ์ž ํ•˜๋Š” identifiers" ๋กœ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค.

๊ทธ๋ž˜์•ผ ์–ด๋–ค namespace์—์„œ ์–ด๋–ค identifier๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ธ์ง€ ๋ช…ํ™•ํ•ด์ง€๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

 

namespace theory{
    void foo() { ... }
    void bar() { ... }
}

namespace practice{
    void foo() { ... }
    void bar() { ... }
}

using theory::foo();
using pratice::bar();

foo(); bar();;