Dynamic Binding (๋™์  ๋ฐ”์ธ๋”ฉ)

๊ทธ๋Ÿฐ๋ฐ, ์šฐ๋ฆฌ๊ฐ€ ๋‘ ํด๋ž˜์Šค๊ฐ€ ์ƒ์†๊ด€๊ณ„์— ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•ˆ๋‹ค๋ฉด, ์ด ๋ฉค๋ฒ„ํ•จ์ˆ˜๋ฅผ ์ž๋™์œผ๋กœ ๋ฌถ์–ด์ค„ ์ˆ˜๋Š” ์—†์„๊นŒ?

์ด์ œย overrideย ,ย virtualย ์˜ ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

#include <iostream>
#include <string>
#include <vector>
 
using namespace std;
 
class Base{
public:
    void f(){cout << "Base::f()" << endl;}
    virtual void vf() {cout << "Base::vf()" << endl;}
};
 
class Derived:public Base{
public:
    void f(){ cout << "Derived::f()" << endl;}
    void vf() override { cout << "Derived::vf()" << endl;}
};
 
int main(){
    
    Base base;
    Derived derived;
    Base* pBase;
    
    pBase = &base;
    pBase->f();
    pBase->vf();
    
    pBase = &derived;
    pBase->f();
    pBase->vf();
    
    return 0;
}
Base::f()
Base::vf()
Base::f()
Derived::vf()
Program ended with exit code: 0

Base ํด๋ž˜์Šค์˜ ์ฃผ์†Œ๋ฅผ ๋‹ด๋Š” ํฌ์ธํ„ฐ ๋ณ€์ˆ˜ย pBaseย ๋ฅผ ์„ ์–ธํ•˜๊ณ , ์ด ์ฃผ์†Œ์—ย baseย ๊ฐ์ฒด์˜ ์ฃผ์†Œ๋ฅผ ๋‹ด๊ณ ์„œ, ๋‘ ๋ฉค๋ฒ„ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋‹ˆ ๋‹น์—ฐํžˆ Base ํด๋ž˜์Šค์˜ ํ•จ์ˆ˜๋“ค์ด ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ,ย derivedย ๊ฐ์ฒด์˜ ์ฃผ์†Œ๋ฅผ ๋‹ด์œผ๋ฉด (๋ถ€๋ชจ ํด๋ž˜์Šค์— ์ž์‹ ํด๋ž˜์Šค๋ฅผ ๋„ฃ์„ ์ˆ˜๋Š” ์žˆ๋‹ค๊ณ  ์•ž๊ธ€์—์„œ ์„ค๋ช…ํ–ˆ๋‹ค.) ๋ฉค๋ฒ„ํ•จ์ˆ˜์˜ย Base์˜ f(), Derived ์˜ vf()ย ๊ฐ€ ํ˜ธ์ถœ๋˜์—ˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

์ฆ‰, ํ•ด๋‹น ๊ฐ์ฒด์˜ ๋ฉค๋ฒ„ํ•จ์ˆ˜๋ฅผ ๊ธฐ๋ณธ์ ์œผ๋กœ๋Š” Base ์—์„œ ๊ฐ€์ ธ์˜จ๋‹ค.

ํ•˜์ง€๋งŒ Virtual ์„ ์–ธ์ด ๋˜์–ด ์žˆ๋‹ค๋ฉด, ์–ด๋–ค ๊ฐ์ฒด์ธ์ง€ ํŒŒ์•…ํ›„ ๊ทธ ๊ฐ์ฒด์˜ ๋ฉค๋ฒ„ํ•จ์ˆ˜๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค

์ด๋Ÿฐ ์ž‘์—…์€, ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋˜๋ฉด์„œ ๋ฌถ์ผ ์ˆ˜ ๋ฐ–์— ์—†์œผ๋ฏ€๋กœ, ๋™์  ๋ฐ”์ธ๋”ฉย ์ด๋ผ ๋ถˆ๋ฆฐ๋‹ค.

๋™์  ๋ฐ”์ธ๋”ฉ์˜ ์˜๋ฏธ

์šฐ๋ฆฌ๋Š” ์ด ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•ด์„œ, ์„œ๋กœ ๋‹ค๋ฅธ ์ž๋ฃŒํ˜•๋“ค์„ ํ•˜๋‚˜์˜ ๋ฒกํ„ฐ์•ˆ์— ๋„ฃ์–ด์„œ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

#include <iostream>
#include <string>
#include <vector>
 
using namespace std;
 
class Base{
public:
    void f(){cout << "Base::f()" << endl;}
    virtual void vf() {cout << "Base::vf()" << endl;}
};
 
class Derived:public Base{
public:
    void f(){ cout << "Derived::f()" << endl;}
    void vf() override { cout << "Derived::vf()" << endl;}
};
 
int main(){
 
    Base* pBase;
    vector<Base*> v{ new Base, new Derived, new Base};
    pBase = new Derived;
    v.push_back(pBase);
    pBase = new Base;
    v.push_back(pBase);
    
    for (auto elem: v)
        elem->vf();
 
    return 0;
}
 
Base::vf()
Derived::vf()
Base::vf()
Derived::vf()
Base::vf()
Program ended with exit code: 0

Baseย ํด๋ž˜์Šค์˜ ์ฃผ์†Œ๋ฅผ ๋‹ด๋Š” ์ž๋ฃŒํ˜•์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฒกํ„ฐ๋ฅผ ๋งŒ๋“ค๊ณ , ๊ทธ ์•ˆ์—, ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ํด๋ž˜์Šค๋ฅผ ๋‹ด์œผ๋ฉด, virtualย overrideย ๊ตฌ์กฐ์— ๋”ฐ๋ผ์„œ ์ž๋™์œผ๋กœ ๋ฉค๋ฒ„ํ•จ์ˆ˜๊ฐ€ ๊ฒฐ์ •๋œ๋‹ค!

Pure virtual function (์ˆœ์ˆ˜ ๊ฐ€์ƒ ํ•จ์ˆ˜)

virtualย ์„ ์„ ์–ธํ•  ๋•Œ, ํŠน๋ณ„ํžˆ ๊ธฐ๋ณธ Base ํด๋ž˜์Šค์—์„œ๋Š” ๊ธฐ๋Šฅ์„ ์ •์˜ํ•˜์ง€ ์•Š๊ณ  ํŒŒ์ƒ ํด๋ž˜์Šค์—์„œ ์ด ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•ด์„œ ์‚ฌ์šฉํ•  ๋•Œ๊ฐ€ ์žˆ๋Š”๋ฐ ์ด๋•Œ ์„ ์–ธํ•˜๋Š” ๊ฒƒ์ด ์ˆœ์ˆ˜ ๊ฐ€์ƒํ•จ์ˆ˜ย ์ด๋‹ค.

virtual print() = 0;

์ˆœ์ˆ˜ ๊ฐ€์ƒํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•  ๋•Œ๋Š”, base ํด๋ž˜์Šค์—์„œ ์ด ํ•จ์ˆ˜์˜ ์ž‘๋™์ด ์—†๋‹ค๋Š” ๊ฒƒ์„ ๋ช…์‹œํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋’ค์—ย =0ย ์„ ์ถ”๊ฐ€๋กœ ๋‹ฌ์•„์ค€๋‹ค.

์ด ํ‘œ์‹œ๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ ์šฐ๋ฆฌ๋Š” ํŒŒ์ƒ ํด๋ž˜์Šค๋กœ๋ถ€ํ„ฐ ์ด ํ•จ์ˆ˜๋ฅผ ํ•„์ˆ˜์ ์œผ๋กœ ์ •์˜ํ•ด์•ผํ•œ๋‹ค.

๋˜ํ•œ Base ํด๋ž˜์Šค์—์„œ ์œ„์™€ ๊ฐ™์ด ์„ ์–ธํ–ˆ์„ ๊ฒฝ์šฐ main ํ•จ์ˆ˜์—์„œ ์šฐ๋ฆฌ๋Š” ์ € ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

abstract Class(์ถ”์ƒ ํด๋ž˜์Šค)

๋‚ด๊ฐ€ ํŒŒ์ƒํด๋ž˜์Šค๋“ค๋กœ ๋ฌด์–ธ๊ฐ€๋ฅผ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์„ ๋•Œ, ๊ทธ ์œ—๋‹จ๊ณ„์—์„œ ์ด ํ•จ์ˆ˜๋“ค์— ๋Œ€ํ•œ ๊ฐœ๋žต์ ์ธ ๊ฒƒ๋“ค์„ ์ ์–ด๋‘” ์ƒ์œ„ ์ง‘ํ•ฉ์˜ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.

์ด ๋•Œ, ์ˆœ์ˆ˜ ๊ฐ€์ƒํ•จ์ˆ˜๋“ค๋กœ ๊ตฌ์„ฑ๋œ ํ•˜๋‚˜์˜ ํด๋ž˜์Šค๋ฅผย ์ถ”์ƒํด๋ž˜์Šคย ๋ผ ๋ถ€๋ฅธ๋‹ค. ์ด๋ ‡๊ฒŒ ๊ด€๋ฆฌํ•  ๊ฒฝ์šฐ ์šฐ๋ฆฌ๋Š” ์–ด๋–ค ํด๋ž˜์Šค๋“ค์˜ ๊ณตํ†ต๋œ ํŠน์ง•์„ ๋ฌถ์–ด์„œ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์šฉ์ดํ•˜๋‹ค.