C++における継承と多態性の実装例

ロボットペットの多態性デモ

pets.hpp

#pragma once
#include <string>
#include <iostream>

class RoboPet {
public:
    RoboPet(const std::string& name);
    virtual std::string vocalize() = 0;
    std::string get_name() const;
private:
    std::string pet_name;
};

RoboPet::RoboPet(const std::string& name) : pet_name{name} {}

std::string RoboPet::get_name() const {
    return pet_name;
}

class RoboCat : public RoboPet {
public:
    RoboCat(const std::string& name);
    std::string vocalize() override;
};

RoboCat::RoboCat(const std::string& name) : RoboPet{name} {}

std::string RoboCat::vocalize() {
    return "nya~ nya~";
}

class RoboDog : public RoboPet {
public:
    RoboDog(const std::string& name);
    std::string vocalize() override;
};

RoboDog::RoboDog(const std::string& name) : RoboPet{name} {}

std::string RoboDog::vocalize() {
    return "wan! wan!";
}

task3.cpp

#include <iostream>
#include <vector>
#include "pets.hpp"

void run_demo() {
    std::vector<RoboPet*> pets;
    pets.push_back(new RoboCat("miku"));
    pets.push_back(new RoboDog("ochan"));

    for (const auto& pet : pets) {
        std::cout << pet->get_name() << ": " << pet->vocalize() << std::endl;
    }
}

int main() {
    run_demo();
}

映画情報管理システム

film.hpp

#pragma once
#include <iomanip>
#include <string>

class Movie {
public:
    friend std::istream& operator>>(std::istream& in, Movie& m);
    friend std::ostream& operator<<(std::ostream& out, const Movie& m);
    friend bool year_comparison(const Movie& a, const Movie& b);
private:
    std::string title;
    std::string director;
    std::string country;
    int release_year;
};

std::istream& operator>>(std::istream& in, Movie& m) {
    std::cout << "Title: "; in >> m.title;
    std::cout << "Director: "; in >> m.director;
    std::cout << "Country: "; in >> m.country;
    std::cout << "Year: "; in >> m.release_year;
    return in;
}

std::ostream& operator<<(std::ostream& out, const Movie& m) {
    out << std::left << std::setw(20) << m.title 
        << std::setw(20) << m.director 
        << std::setw(15) << m.country 
        << std::setw(10) << m.release_year;
    return out;
}

bool year_comparison(const Movie& a, const Movie& b) {
    return a.release_year < b.release_year;
}

task4.cpp

#include "film.hpp"
#include <algorithm>
#include <vector>

void manage_movies() {
    int count;
    std::cout << "Number of movies: ";
    std::cin >> count;

    std::vector<Movie> collection;
    for (int i = 0; i < count; ++i) {
        Movie m;
        std::cin >> m;
        collection.push_back(m);
    }

    std::sort(collection.begin(), collection.end(), year_comparison);
    
    for (const auto& m : collection) {
        std::cout << m << std::endl;
    }
}

int main() {
    manage_movies();
}

テンプレートによる複素数クラス

Complex.hpp

#include <cmath>
#include <iostream>

template <typename T>
class ComplexNum {
public:
    ComplexNum(T r = 0, T i = 0) : real_{r}, imag_{i} {}
    T real() const { return real_; }
    T imag() const { return imag_; }

    ComplexNum<T>& operator+=(const ComplexNum<T>& rhs);
    bool operator==(const ComplexNum<T>& other) const;

    template<typename U>
    friend ComplexNum<U> operator+(const ComplexNum<U>& a, const ComplexNum<U>& b);
    
    template<typename U>
    friend std::istream& operator>>(std::istream& in, ComplexNum<U>& c);
    
    template<typename U>
    friend std::ostream& operator<<(std::ostream& out, const ComplexNum<U>& c);

private:
    T real_;
    T imag_;
};

template<typename T>
bool ComplexNum<T>::operator==(const ComplexNum<T>& other) const {
    return real_ == other.real_ && imag_ == other.imag_;
}

template<typename T>
ComplexNum<T>& ComplexNum<T>::operator+=(const ComplexNum<T>& rhs) {
    real_ += rhs.real_;
    imag_ += rhs.imag_;
    return *this;
}

template<typename T>
ComplexNum<T> operator+(const ComplexNum<T>& a, const ComplexNum<T>& b) {
    return ComplexNum<T>(a.real_ + b.real_, a.imag_ + b.imag_);
}

template<typename T>
std::istream& operator>>(std::istream& in, ComplexNum<T>& c) {
    in >> c.real_ >> c.imag_;
    return in;
}

template<typename T>
std::ostream& operator<<(std::ostream& out, const ComplexNum<T>& c) {
    return out << c.real_ << (c.imag_ >= 0 ? " + " : " - ") << std::abs(c.imag_) << 'i';
}

task5.cpp

#include "Complex.hpp"
#include <iostream>

void complex_test() {
    ComplexNum<double> num1, num2;
    std::cin >> num1 >> num2;
    
    std::cout << "Sum: " << num1 + num2 << '\n';
    std::cout << "Equal: " << std::boolalpha << (num1 == num2) << '\n';
}

int main() {
    complex_test();
}

銀行口座管理システム

date.h

class Date {
private:
    int year_, month_, day_, total_days_;
public:
    Date(int y, int m, int d);
    int year() const { return year_; }
    int month() const { return month_; }
    int day() const { return day_; }
    int max_day() const;
    bool is_leap() const;
    int operator-(const Date& other) const;
};

accumulator.h

class DailyAccumulator {
private:
    Date last_date_;
    double current_value_;
    double accumulated_;
public:
    DailyAccumulator(const Date& start_date, double init_value);
    double accumulated_sum(const Date& to_date) const;
    void update(const Date& on_date, double new_value);
};

account.h

class BankAccount {
protected:
    virtual void apply_interest(const Date& date) = 0;
};

class SavingsAccount : public BankAccount {
private:
    DailyAccumulator interest_acc_;
    double interest_rate_;
public:
    void apply_interest(const Date& date) override;
};

class CreditAccount : public BankAccount {
private:
    DailyAccumulator debt_acc_;
    double credit_limit_;
    double daily_rate_;
    double annual_fee_;
public:
    void apply_interest(const Date& date) override;
};

タグ: C++ 継承 多態性 クラステンプレート STL

6月25日 18:05 投稿