μμμ λͺ©μ
1. Class Relationship (ν΄λμ€ κ΄κ³ νν)
Code Reuse (μ½λ μ¬μ¬μ©)
Class Interface Consistency (μΌκ΄λ μΈν°νμ΄μ€)
μ κ·Ό μ§μ μμ λ°λ₯Έ λ©€λ² μ κ·Ό κΆν λ³ν
class Base
{
public:
int x;
protected:
int y;
private:
int z;
};
1. public μμ (κ°μ₯ μΌλ°μ )
class Derived : public Base
{
// xλ public μ μ§
// yλ protected μ μ§
// zλ μ κ·Ό λΆκ° (privateμ νμ μ κ·Ό λΆκ°)
};
2. protected μμ (λλ¬Όκ² μ¬μ©)
class Derived : protected Base
{
// xλ protectedλ‘ λ³κ²½
// yλ protected μ μ§
// zλ μ κ·Ό λΆκ°
};
3. private μμ (ν΄λμ€μ κΈ°λ³Έκ°)
class Derived : private Base // classλ κΈ°λ³Έκ°μ΄ private
{
// xλ privateλ‘ λ³κ²½
// yλ privateλ‘ λ³κ²½
// zλ μ κ·Ό λΆκ°
};
μ κ·Ό κΆν μ 리 ν
| λΆλͺ¨ ν΄λμ€ | public μμ | protected μμ | private μμ |
|---|---|---|---|
| public | public | protected | private |
| protected | protected | protected | private |
| private | μ κ·Ό λΆκ° | μ κ·Ό λΆκ° | μ κ·Ό λΆκ° |
μ€μ κ°μ΄λλΌμΈ
// β Private μμ (νΌλμ€λ¬μ)
class Car : private Engine { };
// β
Composition (λͺ
νν¨)
class Car {
Engine engine; // Car has an Engine
};
κ°μ ν¨μκ° νμν μ΄μ
class Animal
{
public:
void speak() // μΌλ° ν¨μ
{
std::cout << "Animal sound" << std::endl;
}
};
class Cat : public Animal
{
public:
void speak() // ν¨μ μ¬μ μ (Overriding)
{
std::cout << "Meow~" << std::endl;
}
};
int main()
{
Cat kitty;
Animal* ptr = &kitty; // λΆλͺ¨ νμ
ν¬μΈν°λ‘ μμ κ°μ²΄ μ°Έμ‘°
ptr->speak(); // β "Animal sound" μΆλ ₯ (Catμ speakκ° μλ!)
return 0;
}
λ¬Έμ μ : ν¬μΈν° νμ
μ΄ Animal*μ΄λ―λ‘ μ»΄νμΌ νμμ Animal::speak()κ° νΈμΆλ¨
virtual ν€μλλ‘ ν΄κ²°
class Animal
{
public:
virtual void speak() // β
κ°μ ν¨μλ‘ μ μΈ
{
std::cout << "Animal sound" << std::endl;
}
};
class Cat : public Animal
{
public:
void speak() override // override ν€μλ κΆμ₯
{
std::cout << "Meow~" << std::endl;
}
};
int main()
{
Cat kitty;
Animal* ptr = &kitty;
ptr->speak(); // β
"Meow~" μΆλ ₯ (λ°νμμ μ€μ νμ
νμΈ!)
return 0;
}
Dynamic Binding (λμ λ°μΈλ©)
β μ€μ: Base ν΄λμ€μ μλ©Έμλ λ°λμ virtualλ‘ μ μΈν΄μΌ ν¨
λ¬Έμ μν©
class Animal
{
public:
Animal() { std::cout << "Animal constructor" << std::endl; }
~Animal() { std::cout << "Animal destructor" << std::endl; } // β κ°μ μλ©Έμκ° μλ
};
class Cat : public Animal
{
public:
Cat() { std::cout << "Cat constructor" << std::endl; }
~Cat() { std::cout << "Cat destructor" << std::endl; }
};
int main()
{
Animal* polyCat = new Cat();
// μΆλ ₯:
// Animal constructor
// Cat constructor
delete polyCat;
// μΆλ ₯:
// Animal destructor β Cat destructorκ° νΈμΆλμ§ μμ!
// β λ©λͺ¨λ¦¬ λμ λ°μ!
return 0;
}
ν΄κ²°: κ°μ μλ©Έμ μ¬μ©
class Animal
{
public:
Animal() { std::cout << "Animal constructor" << std::endl; }
virtual ~Animal() { std::cout << "Animal destructor" << std::endl; } // β
virtual μΆκ°
};
class Cat : public Animal
{
public:
Cat() { std::cout << "Cat constructor" << std::endl; }
~Cat() override { std::cout << "Cat destructor" << std::endl; }
};
int main()
{
Animal* polyCat = new Cat();
delete polyCat;
// μΆλ ₯:
// Cat destructor β
μ¬λ°λ₯Έ μμλ‘ νΈμΆλ¨
// Animal destructor
return 0;
}
κ°μ μλ©Έμ κ·μΉ
// β
μ΅μ
1: μμ νμ© + virtual μλ©Έμ
class Base {
public:
virtual ~Base() = default;
};
// β
μ΅μ
2: μμ κΈμ§ (μλ©Έμ protected)
class Base {
protected:
~Base() = default; // μΈλΆμμ delete λΆκ°
};
// β
μ΅μ
3: C++11 final ν€μλ
class Base final { // μμ λΆκ°
public:
~Base() = default;
};
λ©λͺ¨λ¦¬ ꡬ쑰 λ³ν
μΌλ° ν¨μλ§ μλ κ²½μ°
class Animal
{
public:
void speak() { std::cout << "Animal" << std::endl; }
private:
double height; // 8 bytes
};
class Cat : public Animal
{
public:
void speak() { std::cout << "Meow~" << std::endl; }
private:
double weight; // 8 bytes
};
// sizeof(Animal) = 8 bytes (heightλ§)
// sizeof(Cat) = 16 bytes (height + weight)
κ°μ ν¨μκ° μλ κ²½μ°
class Animal
{
public:
virtual void speak() { std::cout << "Animal" << std::endl; }
private:
double height; // 8 bytes
};
class Cat : public Animal
{
public:
void speak() override { std::cout << "Meow~" << std::endl; }
private:
double weight; // 8 bytes
};
// sizeof(Animal) = 16 bytes (vptr 8 + height 8)
// sizeof(Cat) = 24 bytes (vptr 8 + height 8 + weight 8)
Virtual Table (VTable) ꡬ쑰
Animal κ°μ²΄ λ©λͺ¨λ¦¬:
βββββββββββββββ
β vptr (8B) β β Animal VTable
βββββββββββββββ€ ββββββββββββββββββββ
β height (8B)β β&Animal::speak()β
βββββββββββββββ ββββββββββββββββββββ
Cat κ°μ²΄ λ©λͺ¨λ¦¬:
βββββββββββββββ
β vptr (8B) β β Cat VTable
βββββββββββββββ€ ββββββββββββββββββββ
β height (8B)β β &Cat::speak() β
βββββββββββββββ€ ββββββββββββββββββββ
β weight (8B)β
βββββββββββββββ
Virtual Tableμ λμ μ리
1. κ°μ ν¨μκ° μλ ν΄λμ€λ vptr (virtual table pointer) μ κ°μ§ (8 bytes)
2. vptrμ ν΄λΉ ν΄λμ€μ VTableμ κ°λ¦¬ν΄
3. VTableμλ κ°μ ν¨μλ€μ μ€μ μ£Όμκ° μ μ₯λ¨
4. κ°μ ν¨μ νΈμΆ μ vptr β VTable β μ€μ ν¨μ μ£Όμλ‘ κ°μ νΈμΆ
μ±λ₯ κ³ λ €μ¬ν
class Animal
{
public:
virtual void speak() { std::cout << "Animal" << std::endl; }
};
class Cat : public Animal
{
public:
void speak() override { std::cout << "Meow~" << std::endl; }
void meow() { std::cout << "Meow meow!" << std::endl; } // Cat μ μ© ν¨μ
};
int main()
{
Cat kitty;
Animal* ptr = &kitty;
ptr->speak(); // β
OK - κ°μ ν¨μμ΄λ―λ‘ Cat::speak() νΈμΆλ¨
ptr->meow(); // β μ»΄νμΌ μλ¬! Animal νμ
μΌλ‘λ meow() μ κ·Ό λΆκ°
// ν΄κ²° λ°©λ² 1: Cat νμ
ν¬μΈν° μ¬μ©
Cat* catPtr = &kitty;
catPtr->meow(); // β
OK
// ν΄κ²° λ°©λ² 2: λ€μ΄μΊμ€ν
(κΆμ₯νμ§ μμ)
Cat* catPtr2 = static_cast<Cat*>(ptr);
catPtr2->meow(); // β
OK (νμ§λ§ μνν¨)
return 0;
}
ν΅μ¬ μμΉ
μμ κ°μ ν¨μ μ μΈ
class Animal
{
public:
virtual void speak() = 0; // β
μμ κ°μ ν¨μ
// = 0 μ "ꡬνμ΄ μμ"μ μλ―Έ
};
Abstract Class (μΆμ ν΄λμ€)
class Animal // Abstract class
{
public:
virtual void speak() = 0; // μμ κ°μ ν¨μ
virtual void eat() { std::cout << "Eating" << std::endl; } // μΌλ° κ°μ ν¨μλ κ°λ₯
virtual ~Animal() = default;
};
class Cat : public Animal
{
public:
void speak() override { std::cout << "Meow~" << std::endl; } // β
ꡬν νμ
};
class Dog : public Animal
{
// β speak()λ₯Ό ꡬννμ§ μμ β Dogλ μΆμ ν΄λμ€κ° λ¨
};
int main()
{
Animal animal; // β μ»΄νμΌ μλ¬! μΆμ ν΄λμ€λ κ°μ²΄ μμ± λΆκ°
Cat kitty; // β
OK - speak()λ₯Ό ꡬννμΌλ―λ‘
Dog puppy; // β μ»΄νμΌ μλ¬! Dogλ μΆμ ν΄λμ€
Animal* ptr = new Cat(); // β
OK - ν¬μΈν°λ κ°λ₯
ptr->speak(); // "Meow~"
delete ptr;
return 0;
}
μΈν°νμ΄μ€ μ μ
// β
μ’μ μΈν°νμ΄μ€ μ€κ³
class IDrawable // I μ λμ¬λ μΈν°νμ΄μ€ νμ (κ΄λ‘)
{
public:
virtual void draw() = 0;
virtual void setColor(int r, int g, int b) = 0;
virtual ~IDrawable() = default; // κ°μ μλ©Έμλ νμ
// λ©€λ² λ³μ μμ
// ꡬνλ ν¨μ μμ
};
class Circle : public IDrawable
{
public:
void draw() override { /* μ 그리기 ꡬν */ }
void setColor(int r, int g, int b) override { /* μμ μ€μ ꡬν */ }
private:
double radius;
int red, green, blue;
};
μΈν°νμ΄μ€ μ€κ³ μμΉ
virtual ~IDrawable() = default;class IDrawable
{
public:
virtual void draw() = 0;
virtual ~IDrawable() = default;
protected:
IDrawable() = default; // μμ±μ protected
IDrawable(const IDrawable&) = delete; // λ³΅μ¬ κΈμ§
IDrawable& operator=(const IDrawable&) = delete;
};μΈν°νμ΄μ€ μ¬μ©μ μ₯μ
// λμ μ€κ³: ꡬ체 ν΄λμ€μ μμ‘΄
void processImage(JPEGImage& img) { /* ... */ }
// μ’μ μ€κ³: μΈν°νμ΄μ€μ μμ‘΄
void processImage(IImage& img) { /* ... */ }
// JPEG, PNG, BMP λ± λ€μν ꡬν체 μ¬μ© κ°λ₯
μ€μ μμ : λ€μ€ μΈν°νμ΄μ€ ꡬν
class ISerializable
{
public:
virtual std::string serialize() = 0;
virtual void deserialize(const std::string& data) = 0;
virtual ~ISerializable() = default;
};
class ILoggable
{
public:
virtual void log() = 0;
virtual ~ILoggable() = default;
};
class User : public ISerializable, public ILoggable
{
public:
std::string serialize() override { /* JSON λ³ν */ }
void deserialize(const std::string& data) override { /* JSON νμ± */ }
void log() override { /* λ‘κ·Έ μΆλ ₯ */ }
private:
std::string name;
int age;
};
μμ μ¬μ© κ°μ΄λλΌμΈ
1. public μμλ§ μ¬μ© (99%μ κ²½μ°)
2. Base ν΄λμ€ μλ©Έμλ virtual public λλ protected
3. λ€νμ±μ΄ νμνλ©΄ virtual ν¨μ μ¬μ©
4. μΈν°νμ΄μ€λ μμ κ°μ ν¨μλ§μΌλ‘ ꡬμ±
5. override ν€μλλ‘ μλ λͺ
νν νν
// β
μ¬λ°λ₯Έ μμ ꡬ쑰
class IAnimal // μΈν°νμ΄μ€
{
public:
virtual void speak() = 0;
virtual ~IAnimal() = default;
};
class Animal : public IAnimal // μΆμ ν΄λμ€
{
public:
void speak() override { std::cout << "Animal" << std::endl; }
virtual ~Animal() = default;
protected:
int age; // κ³΅ν΅ λ°μ΄ν°
};
class Cat final : public Animal // ꡬ체 ν΄λμ€ (finalλ‘ λ μ΄μ μμ κΈμ§)
{
public:
void speak() override { std::cout << "Meow~" << std::endl; }
};
μ½λμλ νλ‘κ·Έλλ°
C++ Inheritance
C++ Virtual Functions