C++ Structures and Classes 완전 정리

gigyesik·2025년 6월 20일

developer-roadmap-c++

목록 보기
9/20

C++ Structures and Classes 완전 정리 🚀

C++에서 구조체(struct)와 클래스(class)는 데이터를 그룹화하고 객체 지향 프로그래밍(OOP)을 실현하는 핵심 요소다. 이번 글에서는 C++ 로드맵의 Structures and Classes 파트를 중심으로 구조체와 클래스의 기본 개념부터 OOP, 다형성, 상속, 그리고 Rule of 0/3/5까지 차근차근 정리해본다.


📦 구조체와 클래스

구조체 (struct)

  • 다양한 타입의 데이터를 하나의 이름 아래 묶을 수 있는 사용자 정의 자료형
  • 기본 접근 제어자는 public
struct Employee {
    int id;
    std::string name;
    float salary;
};

Employee e1;
e1.id = 1;
e1.name = "John Doe";
e1.salary = 40000;

클래스 (class)

  • 구조체와 유사하지만, 기본 접근 제어자는 private
  • 멤버 함수와 데이터 캡슐화 기능을 제공
class Student {
    int roll_no;
    std::string name;
    float marks;

public:
    void set_data(int r, std::string n, float m) {
        roll_no = r;
        name = n;
        marks = m;
    }

    void display() {
        std::cout << "Roll no: " << roll_no
                  << "\nName: " << name
                  << "\nMarks: " << marks << '\n';
    }
};

Student s1;
s1.set_data(1, "Alice", 95.0);
s1.display();

🧱 객체 지향 프로그래밍 (OOP)

캡슐화 (Encapsulation)

  • 데이터와 함수의 묶음
  • private, public 접근 제어자 사용
class Dog {
private:
    std::string name;
    int age;

public:
    void setName(std::string n) { name = n; }
    void setAge(int a) { age = a; }
    void bark() { std::cout << name << " barks!\n"; }
};

상속 (Inheritance)

  • 기존 클래스의 기능을 재사용
  • : 기호와 접근 지정자를 사용
class Animal {
public:
    void breathe() { std::cout << "I can breathe\n"; }
};

class Dog : public Animal {
public:
    void bark() { std::cout << "Dog barks!\n"; }
};

Dog myDog;
myDog.breathe();
myDog.bark();

다형성 (Polymorphism)

  • 하나의 인터페이스로 다양한 동작을 수행
class Animal {
public:
    virtual void makeSound() {
        std::cout << "The Animal makes a sound\n";
    }
};

class Dog : public Animal {
public:
    void makeSound() override {
        std::cout << "Dog barks!\n";
    }
};

class Cat : public Animal {
public:
    void makeSound() override {
        std::cout << "Cat meows!\n";
    }
};

Animal* animals[2] = {new Dog, new Cat};
animals[0]->makeSound(); // Dog barks!
animals[1]->makeSound(); // Cat meows!

🔁 동적 다형성 (Dynamic Polymorphism)

  • 런타임에 어떤 함수가 호출될지 결정
  • virtual 키워드를 사용
class Shape {
public:
    virtual void draw() {
        std::cout << "Drawing a shape\n";
    }
};

class Circle : public Shape {
public:
    void draw() override {
        std::cout << "Drawing a circle\n";
    }
};

Shape* shape = new Circle();
shape->draw(); // Drawing a circle

🔗 다중 상속 (Multiple Inheritance)

  • 여러 개의 부모 클래스로부터 상속 가능
class Animal {
public:
    void eat() { std::cout << "I can eat!\n"; }
};

class Mammal {
public:
    void breath() { std::cout << "I can breathe!\n"; }
};

class Dog : public Animal, public Mammal {
public:
    void bark() { std::cout << "I can bark!\n"; }
};

💎 다이아몬드 상속 문제와 해결

  • 두 클래스가 같은 기반 클래스를 상속하고, 또 다른 클래스가 이 둘을 상속할 때 발생
  • virtual 키워드를 이용한 가상 상속으로 해결
class Base {
public:
    void print() { std::cout << "Base class\n"; }
};

class Derived1 : virtual public Base {};
class Derived2 : virtual public Base {};
class Derived3 : public Derived1, public Derived2 {};

Derived3 d3;
d3.print(); // Base class

🧠 Rule of Zero / Three / Five

Rule of Zero

  • 자원 관리가 필요 없으면 특별한 함수들을 정의하지 않아도 된다.
struct MyResource {
    std::string name;
    int value;
};

Rule of Three

  • 자원을 직접 관리하면 반드시 세 가지를 정의해야 한다
    • 소멸자
    • 복사 생성자
    • 복사 대입 연산자
class MyResource {
public:
    MyResource() : data(new int[100]) {}
    ~MyResource() { delete[] data; }

    MyResource(const MyResource& other) : data(new int[100]) {
        std::copy(other.data, other.data + 100, data);
    }

    MyResource& operator=(const MyResource& other) {
        if (this == &other) return *this;
        std::copy(other.data, other.data + 100, data);
        return *this;
    }

private:
    int* data;
};

Rule of Five

  • Rule of Three에 다음 둘을 추가로 정의해야 한다
    • 이동 생성자
    • 이동 대입 연산자
class MyResource {
public:
    MyResource() : data(new int[100]) {}
    ~MyResource() { delete[] data; }

    MyResource(const MyResource& other) : data(new int[100]) {
        std::copy(other.data, other.data + 100, data);
    }

    MyResource& operator=(const MyResource& other) {
        if (this == &other) return *this;
        std::copy(other.data, other.data + 100, data);
        return *this;
    }

    MyResource(MyResource&& other) noexcept : data(other.data) {
        other.data = nullptr;
    }

    MyResource& operator=(MyResource&& other) noexcept {
        if (this == &other) return *this;
        delete[] data;
        data = other.data;
        other.data = nullptr;
        return *this;
    }

private:
    int* data;
};

✅ 마무리

C++의 구조체와 클래스는 단순히 데이터를 묶는 것에서 그치지 않고, 객체 지향적인 사고로 설계를 가능하게 해준다. 캡슐화, 상속, 다형성, 그리고 Rule of Zero, Three, Five까지 잘 익혀두면 견고하고 유연한 C++ 코드를 작성할 수 있다.

profile
Server Dev

0개의 댓글