C++ 기반 GUI 시뮬레이션과 컨테이너 클래스 구현

작업 1: GUI 요소의 조합 설계

이 작업은 C++에서 버튼과 창을 모델링하여 간단한 GUI를 시뮬레이션합니다. Button 클래스는 레이블을 가지고 클릭 시 메시지를 출력하며, Window 클래스는 여러 개의 버튼을 포함하는 조합 관계를 가집니다.

핵심 코드

#include <iostream>
#include <string>
#include <vector>

class Button {
public:
    explicit Button(const std::string& label);
    const std::string& get_label() const;
    void click();

private:
    std::string label_;
};

Button::Button(const std::string& label) : label_{label} {}

const std::string& Button::get_label() const {
    return label_;
}

void Button::click() {
    std::cout << "Button '" << label_ << "' activated\n";
}

class Window {
public:
    explicit Window(const std::string& title);
    void show() const;
    void terminate();
    void add_button(const std::string& label);
    void trigger(const std::string& label);

private:
    bool contains(const std::string& label) const;

private:
    std::string title_;
    std::vector<Button> controls;
};

Window::Window(const std::string& title) : title_{title} {
    controls.emplace_back("close");
}

void Window::show() const {
    std::string border(40, '=');
    std::cout << border << "\n";
    std::cout << "window: " << title_ << "\n";
    int idx = 0;
    for (const auto& btn : controls)
        std::cout << ++idx << ". " << btn.get_label() << "\n";
    std::cout << border << "\n";
}

void Window::terminate() {
    std::cout << "closing window '" << title_ << "'\n";
    trigger("close");
}

bool Window::contains(const std::string& label) const {
    return std::any_of(controls.begin(), controls.end(),
                       [&](const Button& b) { return b.get_label() == label; });
}

void Window::add_button(const std::string& label) {
    if (contains(label))
        std::cout << "duplicate button: " << label << "\n";
    else
        controls.emplace_back(label);
}

void Window::trigger(const std::string& label) {
    auto it = std::find_if(controls.begin(), controls.end(),
                           [&](const Button& b) { return b.get_label() == label; });
    if (it != controls.end())
        it->click();
    else
        std::cout << "missing button: " << label << "\n";
}

실행 예제

int main() {
    std::cout << "GUI 시뮬레이션 시작:\n";
    Window win{"메인"};
    win.add_button("추가");
    win.add_button("삭제");
    win.add_button("수정");
    win.add_button("추가");  // 중복
    win.show();
    win.terminate();
    return 0;
}

작업 2: 벡터의 깊은 복사 검증

이 섹션에서는 std::vector의 복사 생성자가 얕은 복사가 아닌 깊은 복사를 수행함을 입증합니다. 내부 데이터가 독립적으로 유지되므로 한 객체의 수정이 다른 객체에 영향을 주지 않습니다.

void test_deep_copy() {
    std::vector<int> src(5, 99);
    const std::vector<int> dst(src);  // 깊은 복사

    std::cout << "src: ";
    for (const auto& e : src) std::cout << e << " ";
    std::cout << "\ndst: ";
    for (const auto& e : dst) std::cout << e << " ";

    src[0] = -5;
    std::cout << "\nsrc[0] 변경 후:\n";
    std::cout << "src: " << src[0] << ", dst: " << dst[0] << "\n";  // dst[0] == 99
}

작업 3: 사용자 정의 정수 벡터 클래스

vectorInt 클래스는 동적 배열 기반의 컨테이너로, 복사 생성자와 대입 연산자를 통해 안전한 메모리 관리를 제공합니다.

class vectorInt {
public:
    vectorInt();
    vectorInt(int size);
    vectorInt(int size, int value);
    vectorInt(const vectorInt& other);
    ~vectorInt();

    int size() const;
    int& at(int index);
    const int& at(int index) const;
    vectorInt& operator=(const vectorInt& other);

    int* begin();
    int* end();
    const int* begin() const;
    const int* end() const;

private:
    int count;
    int* data;
};

// const 멤버 함수 재사용을 위한 const_cast 활용
int& vectorInt::at(int index) {
    return const_cast<int&>(static_cast<const vectorInt*>(this)->at(index));
}

작업 4: 행렬 클래스 설계

Matrix 클래스는 2차원 배열을 모델링하며, 요소 접근, 초기화, 출력 등의 기능을 제공합니다.

class Matrix {
public:
    Matrix(int rows, int cols, double val = 0.0);
    Matrix(const Matrix& other);
    ~Matrix();

    void set(const double* values, int length);
    void clear();
    double& at(int i, int j);
    const double& at(int i, int j) const;
    void print() const;

    int rows() const;
    int cols() const;

private:
    int rows_, cols_;
    double* buffer;
};

작업 5: 연락처 관리 시스템

ContactBook 클래스는 이름 기준으로 정렬된 연락처 목록을 관리하며, 추가, 삭제, 검색 기능을 제공합니다.

class ContactBook {
public:
    void add(const std::string& name, const std::string& phone);
    void remove(const std::string& name);
    void find(const std::string& name) const;
    void display() const;

private:
    int find_index(const std::string& name) const;
    void sort_by_name();

    std::vector<Contact> entries;
};

void ContactBook::sort_by_name() {
    std::sort(entries.begin(), entries.end(),
              [](const Contact& a, const Contact& b) {
                  return a.get_name() < b.get_name();
              });
}

태그: cpp OOP composition MemoryManagement STL

7월 21일 05:42에 게시됨