LoginSignup
2
0

More than 5 years have passed since last update.

はじめてのC++【18日目】

Posted at

はじめに

外出先にwifiが飛んでいないというまさかの環境です。
pcが使えないためスマホで投稿しているので、教科書の内容に沿って進めることだけにします。

ロベールのC++【18日目】

07-01 昨日の続き

昨日作ったInputStreamArrayStreamは、同じような形である。大ざっぱに見れば「0以上の値を順次取得していく処理」という同じ処理のクラス。
これは、その値の源がキーボードからの入力か、それとも配列からのという違いがあるだけでほとんど同じ。こういう場合は、その共通部分を抜き出していつ1つクラスを作ることができる。そして、その共通部分をまとめたクラスを基底クラスという。また、基底クラスを基にして作られたクラスを派生クラスという。そして、基底クラスを基にして派生クラスを作ることを「継承」あるいは「派生」と言う。

派生クラスはその基底クラスのメンバを引き継ぐ。派生クラスでは、足りないメンバを定義すればいいことになります。基底クラスから派生クラスへとメンバが受け継がれることを「継承」という。

基底クラスStream.hを作る。

Stream.h
#ifndef STREAM_H_
#define STREAM_H_

//0以上の値を順次取得していく処理行うための基底クラス
class Stream {
public:
  double Get() const;//設定された値を取得

public:
  double m_n; //現在の値
};

#endif 
Stream.cpp
#include "Stream.h"

//設定された値を取得
double Stream::Get() const {
  return m_n;
}
Average2.cpp
#include "InputStream2.h"
#include <iostream>

bool
Average(InputStream& stream) {
  int count;
  double avr = 0;

  for(count = 0; stream.Set(); ++count) {
    avr += stream.Get();
  }

  if(count == 0){
    return false;
  }

  avr /= count;
  std::cout << "平均値は " << avr << "です。" << std::endl;
  return true;
}

int main(){
  while(true){
    InputStream stream;
    if(!Average(stream)){
      break;
    }
  }
}
InputStream2.h
#ifndef INPUTSTREAM2_H_
#define INPUTSTREAM2_H_

#include "Stream.h"

//入力クラス
class InputStream :
  public Stream
{
public:
  bool Set(); //入力関数
};

#endif
InputStream2.cpp
#include "InputStream.h"
#include <iostream>

//入力関数
bool
InputStream::Set(){
  std::cin >> m_n;
  return m_n >= 0;
}

これで実行すると前とおなじ実行結果が出てきた。

ArrayStream2.h
#ifndef ARRAYSTREAM2_H_
#define ARRAYSTREAM2_H_

#include "Stream.h"

class ArrayStream :
  public Stream
{
public:
  ArrayStream(const double* array);
  bool Set(); //新しい値を設定

private:
  const double* m_array;//配列
  int m_i; //現在のインデックス
};

#endif
ArrayStream2.cpp
#include "ArrayStream2.h"

ArrayStream::ArrayStream(const double* array) {
  m_array = array;
  m_i = 0;
}

bool ArrayStream::Set() {
  m_n = m_array[m_i];
  if(m_n >= 0){
    ++m_i;
    return true;
  }else{
  return false;
  }
}
Average3.cpp
#include "ArrayStream2.h"
#include <iostream>

bool
Average(ArrayStream& stream) {
  int count;
  double avr = 0;

  for(count = 0; stream.Set(); ++count) {
    avr += stream.Get();
  }

  if(count == 0){
    return false;
  }

  avr /= count;
  std::cout << "平均値は " << avr << "です。" << std::endl;
  return true;
}

int main(){
  static const double ARRAY1[] = { 1, 2, 3, -1};
  static const double ARRAY2[] = { 1.5, 0.5, -1};
  static const double ARRAY3[] = { -1 };
  static const double* ARRAY[] = { ARRAY1, ARRAY2, ARRAY3};
  static const int SIZE = sizeof ARRAY / sizeof *ARRAY;

  for(int i = 0; i < SIZE; ++i){
    ArrayStream stream(ARRAY[i]);
    if(!Average(stream)){
      break;
    }
  }
}

このように継承を利用したら複数のクラスの共通部分を一箇所にまとめることができる。

終わりに

今日はここまで!
おやすみなさい

2
0
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0