C++에서 객체 지향 프로그래밍(OOP)은 상속, 다형성, 가상 함수, 순수 가상 함수, 오버로딩 등 다양한 개념을 포함합니다. 각 개념을 자세히 설명하겠습니다.
상속 (Inheritance)
상속은 기존 클래스(부모 클래스)의 특성을 새로운 클래스(자식 클래스)가 물려받는 것을 의미합니다. 이는 코드의 재사용성을 높이고, 클래스 간 계층 구조를 형성할 수 있도록 합니다.
#include <iostream> // 부모 클래스 class Shape { protected: int width, height; public: Shape(int w, int h) : width(w), height(h) {} void setWidth(int w) { width = w; } void setHeight(int h) { height = h; } }; // 자식 클래스 class Rectangle : public Shape { public: Rectangle(int w, int h) : Shape(w, h) {} int getArea() { return width * height; } }; int main() { Rectangle rect(5, 10); std::cout << "사각형의 넓이: " << rect.getArea() << std::endl; return 0; }
다형성 (Polymorphism)
다형성은 같은 이름의 메서드가 서로 다른 클래스에서 다르게 작동할 수 있는 능력을 말합니다. C++에서는 함수 오버로딩과 가상 함수(Virtual Functions)를 통해 구현됩니다.
함수 오버로딩 (Function Overloading)
함수 오버로딩은 같은 이름의 함수를 여러 개 정의하고 매개변수의 타입이나 개수에 따라 호출될 함수가 결정되는 것을 의미합니다.
#include <iostream> class OverloadExample { public: void print(int num) { std::cout << "정수: " << num << std::endl; } void print(double num) { std::cout << "실수: " << num << std::endl; } }; int main() { OverloadExample obj; obj.print(5); // int 매개변수를 가진 함수 호출 obj.print(3.14); // double 매개변수를 가진 함수 호출 return 0; }
가상 함수 (Virtual Functions)
가상 함수는 기본 클래스에서 선언되고 파생 클래스에서 재정의할 수 있는 함수입니다. 런타임에 객체의 실제 타입에 따라 적절한 함수가 호출됩니다.
#include <iostream> // 기본 클래스 class Animal { public: virtual void sound() { std::cout << "동물 소리" << std::endl; } }; // 파생 클래스 class Dog : public Animal { public: void sound() override { std::cout << "멍멍" << std::endl; } }; // 파생 클래스 class Cat : public Animal { public: void sound() override { std::cout << "야옹" << std::endl; } }; int main() { Animal* animal; Dog dog; Cat cat; animal = &dog; animal->sound(); // Dog 클래스의 sound 함수 호출 animal = &cat; animal->sound(); // Cat 클래스의 sound 함수 호출 return 0; }
순수 가상 함수 (Pure Virtual Functions)
순수 가상 함수는 기본 클래스에서 선언되고, 파생 클래스에서 반드시 재정의해야 하는 가상 함수입니다. 순수 가상 함수를 포함하는 클래스를 추상 클래스라고 합니다.
#include <iostream> // 추상 클래스 class Shape { public: // 순수 가상 함수 virtual void draw() = 0; // 일반 함수 void display() { std::cout << "도형을 그립니다." << std::endl; } }; // 파생 클래스 class Rectangle : public Shape { public: void draw() override { std::cout << "사각형을 그립니다." << std::endl; } }; int main() { // Shape shape; // 추상 클래스는 객체를 생성할 수 없음 Rectangle rect; rect.draw(); rect.display(); return 0; }
예제 프로그램
위의 예제들을 종합한 프로그램입니다. 상속, 다형성, 가상 함수 등의 개념을 함께 사용하여 객체 지향 프로그래밍을 구현하였습니다.
#include <iostream> // 부모 클래스 class Animal { public: virtual void sound() { std::cout << "Animal sound" << std::endl; } }; // 파생 클래스 class Dog : public Animal { public: void sound() override { std::cout << "멍멍" << std::endl; } }; // 파생 클래스 class Cat : public Animal { public: void sound() override { std::cout << "야옹" << std::endl; } }; int main() { Animal* animal; Dog dog; Cat cat; animal = &dog; animal->sound(); // Dog 클래스의 sound 함수 호출 animal = &cat; animal->sound(); // Cat 클래스의 sound 함수 호출 return 0; }
이 예제는 상속을 통해 다형성을 구현하고, 가상 함수를 사용하여 런타임에 적절한 함수가 호출되도록 하였습니다. 객체 지향 프로그래밍의 강력한 기능들을 적절히 활용하여 코드를 재사용하고 확장할 수 있습니다.