クラステンプレート 解答ページ | Programming Place Plus Modern C++編【言語解説】 第8章

トップページModern C++編 C++編](../../index.html) – 第8章

Modern C++編は作りかけで、更新が停止しています。代わりに、C++14 をベースにして、その他の方針についても見直しを行った、新C++編を作成しています。
Modern C++編は削除される予定です。

問題①

問題① 生徒を表す Studentクラスで、国語、英語、数学の得点を管理したいとします。 テンプレート仮引数 T と SIZE を持つ Numbersクラステンプレートを用いて、実現してください。 (問題に関係がない部分は、任意で構いません)。


たとえば、次のようになります。 Numbers については本編の最終形と同じなので、省略します。

// Student.h

#ifndef STUDENT_H_INCLUDED
#define STUDENT_H_INCLUDED

#include "Numbers.h"
#include "Subject.h"

class Student {
public:
    Student(const char* name, int grade, const int* scores);
    ~Student();

    const char* GetName() const;
    int GetGrade() const;
    int GetSumScore() const;
    int GetAverageScore() const;

private:
    char mName[32];                           // 名前
    const int mGrade;                         // 学年
    const Numbers<int, SUBJECT_NUM> mScores;  // 得点
};

#endif
// Student.cpp

#include "Student.h"
#include <cstring>

Student::Student(const char* name, int grade, const int* scores) :
    mGrade(grade), mScores(scores)
{
    std::strcpy(mName, name);
}

Student::~Student()
{
}

const char* Student::GetName() const
{
    return mName;
}

int Student::GetGrade() const
{
    return mGrade;
}

int Student::GetSumScore() const
{
    return mScores.Sum();
}

int Student::GetAverageScore() const
{
    return mScores.Average();
}
// Subject.h

#ifndef SUBJECT_H_INCLUDED
#define SUBJECT_H_INCLUDED

enum Subject {
    SUBJECT_JAPANESE,
    SUBJECT_ENGLISH,
    SUBJECT_MATH,

    SUBJECT_NUM
};

#endif
// main.cpp

#include <iostream>
#include "Student.h"

namespace {
    void PrintStudentScores(const Student* student)
    {
        std::cout << "name: " << student->GetName() << "\n"
                  << "grade: " << student->GetGrade() << "\n"
                  << "sum score: " << student->GetSumScore() << "\n"
                  << "avg score: " << student->GetAverageScore() << "\n"
                  << std::endl;
    }
}

int main()
{
    const int scores1[] = { 80, 62, 73 };
    Student student1("Saitou Takashi", 2, scores1);
    
    const int scores2[] = { 75, 77, 60 };
    Student student2("Yamamoto Yuko", 1, scores2);


    PrintStudentScores(&student1);
    PrintStudentScores(&student2);
}

実行結果:

name: Saitou Takashi
grade: 2
sum score: 215
avg score: 71

name: Yamamoto Yuko
grade: 1
sum score: 212
avg score: 70

このサンプルでは必要ありませんが、 もう少し現実的な例であれば、教科ごとの得点を出力するぐらいのことは必要になるはずなので、 一応、Subject(教科)の enum を定義してみました。

問題②

問題② 任意の型の3つの値を管理できるクラステンプレートを作ってみてください。


Numbersクラステンプレートの最終形と違い、個数は3つに固定されていますが、 型はばらばらにできるようにしなければなりませんから、 テンプレート仮引数が3つ必要です。

// ThreeValues.h

template <typename T1, typename T2, typename T3>
class ThreeValues {
public:
    using first_type = T1;
    using second_type = T2;
    using third_type = T3;

public:
    ThreeValues(T1 first, T2 second, T3 third) :
        mFirst(first), mSecond(second), mThird(third)
    {}
    
    inline first_type GetFirstValue() const
    {
        return mFirst;
    }
    inline second_type GetSecondValue() const
    {
        return mSecond;
    }
    inline third_type GetThirdValue() const
    {
        return mThird;
    }

private:
    const T1   mFirst;
    const T2   mSecond;
    const T3   mThird;
};
// main.cpp

#include "ThreeValues.h"
#include <iostream>

int main()
{
    using ValuesType1 = ThreeValues<char, int, int>;
    using ValuesType2 = ThreeValues<const char*, bool, double>;

    const ValuesType1 values1('X', 50, 100);
    const ValuesType2 values2("xxx", true, 3.5);
    
    std::cout << values1.GetFirstValue() << " "
              << values1.GetSecondValue() << " "
              << values1.GetThirdValue() << std::endl;
    std::cout << values2.GetFirstValue() << " "
              << values2.GetSecondValue() << " "
              << values2.GetThirdValue() << std::endl;
}

実行結果:

X 50 100
xxx 1 3.5



参考リンク


更新履歴

’2017/7/23 新規作成。



第8章のメインページへ

Modern C++編のトップページへ

Programming Place Plus のトップページへ



はてなブックマーク に保存 Pocket に保存 Facebook でシェア
X で ポストフォロー LINE で送る noteで書く
rss1.0 取得ボタン RSS 管理者情報 プライバシーポリシー
先頭へ戻る