C++ ⇒ VBA 書いて覚えるための初心者自己中記事

C++ ⇒ VBA 勉強の履歴を付けるというかノート代わりに使ってます

C++ class とそれに関係してくるものを書いて覚えるための初心者自己中記事⑤

 

nenechi.hatenablog.com

 の続き

 

意図としては派生クラスを宣言時に基底クラスのコンストラクタが動いた段階で

SetBase関数 ( 純粋仮想関数 ) を呼び出して当該派生クラスのSetBase関数を呼び出させようとした。

---------------------------------------------------

//Input class //抽象クラス

Input::Input(double n){

    SetBase(); //純粋仮想関数をかくとエラー

    inputNum = n;

}

 

double Input::Get(){

    return inputNum;

}

 

bool Input::Set(){

    SetBase();

    return inputNum > 0;

}

---------------------------------------------------

エラーになる。

 

これはコンストラクタの呼ばれる順番が関係していて、基底クラスのコンストラクタが呼び出されている時点では派生クラスのコンストラクタはまだ呼び出されておらず、

基底クラスのコンストラクタ内で純粋仮想関数を呼び出すと、実装されてないよ!ってエラーになる。派生クラスのSerBase関数はこの段階では認識されていない?のだ。

 

 

なので今回の意図を達成するためにはそれぞれ派生クラスのコンストラクタ内の処理で行う必要がある。

 

前回記述したコンストラクタ・デストラクタの順番に追加すると。

基底クラスのコンストラクタ(基底クラスで使用できるメンバのみ)

派生クラスのコンストラクタ

派生クラスのデストラクタ

基底クラスのデストラクタ (基底クラスで使用できるメンバのみ)

 

なのだ。

 

 

次、

スコープ解決演算子

 

InputCin classではSetBase関数内で cin を使って入力した値を inputNum に代入していました。

次にInputCin class を継承したHalfInputCin class を作成します。

このクラスではSetBase 関数内で親クラスのSetBase 関数を呼び出し、その後inputNumに代入された値を半分にする処理を書きます。

 

その際HalfInputCin class 内でInputCin class の関数を呼び出しす方法が

スコープ解決演算子です。

使い方は簡単で、変数の呼び出し部分で先頭に 当該クラス名::

をつけるだけです。

 

 

---------------------------------------------------

// InputCin class の派生クラス

class HalfInputCin : public InputCin{

protected:

    virtual void SetBase();

};

~~~~~~~~~~~~~~~~~~~~~~

//HalfInputCin class (InputCin class の派生クラス)

void HalfInputCin::SetBase(){

    InputCin::SetBase();

    inputNum /= 2;

}

---------------------------------------------------

これで呼び出せます。

 

 

あと、前回の勉強でやった仮想関数で基底クラスから派生クラスの当該メンバ関数を呼び出す流れはデストラクタでも同様。

 

 とりあえずクラスは一旦終わった。

最後に出来上がった(テキストまま)のをメモ

---------------------------------------------------

// Input class 基底クラス

class Input{

public:

    Input(); //コンストラクタ

    virtual ~Input() = 0;

    double Get(); //共通点

    bool Set(); // Set関数内ではSetBase関数を呼び出す その後0以上かをチェックする

protected:

    virtual void SetBase() = 0; //Set関数から値の設定部分を抜き出した SetBase関数が仮想関数になるので各派生クラスもそれに準じる

    double inputNum; //共通点

};

 

// InputCin vlass 派生クラス

class InputCin : public Input{

public:

    InputCin();

    virtual void SetBase();

private:

};

 

// InputArray class 派生クラス

class InputArray : public Input{ // class InputArrayは配列の管理

public:

    InputArray(const double* array, int size); //配列を受け取る引数付きコンストラクタ

    virtual ~InputArray();

    virtual void SetBase(); //Set関数が呼び出されるたびにinputIndexinputNumに次のインデックス番号と数値が記憶される

    

private:

    double* inputArray; //配列のアドレスポインタ

    int inputIndex; //Set関数で現在のインデックスを記憶

    

};

~~~~~~~~~~~~~~~~~~~~~~

//Input class

Input::Input(){

    

}

 

double Input::Get(){

    return inputNum;

}

 

bool Input::Set(){

    SetBase();

    return inputNum > 0;

}

 

 

//InputCin class

InputCin::InputCin(){

}

void InputCin::SetBase(){

    cin >> inputNum;

    

}

 

//InputArray class

InputArray::InputArray(const double* array, int size){

    inputArray = new double[size];

    copy(array,array + size,   inputArray);

    inputIndex = 0;

}

InputArray::~InputArray(){

    delete[ ] inputArray;

}

 

void InputArray::SetBase(){

    inputNum = inputArray[inputIndex];

    ++inputIndex;

}

~~~~~~~~~~~~~~~~~~~~~~

//Average関数

void Average(Input& input){

    int count = 0;

    double avr = 0.0;

    

    while(input.Set()){

        avr += input.Get();

        ++count;

    }

    avr /= count;

    cout << avr << endl;

}

 

 

 

void Show(Input& input){ //基底クラスで派生クラスのオブジェクトを参照する

    input.Set();

    cout << input.Get() << endl; //派生クラスを参照している基底クラスがGet関数を使う

}

 

Input* CreateInput(){

    int ch;

    cout << "1.InpotCin  2.InputArray" << endl;

    cin >> ch;

    

    switch(ch){

        case 1:

            return new InputCin;

            break;

            

        case 2:

            static const double array[ ] = {1.1,2.2,3.3,4.4,-1,};

            return new InputArray(array,5);

            break;

            

        default:

            return 0;

 

    }

}

 

 

int main(){

    Input* input = CreateInput();

    Average(*input);

    delete input;

    

 

}

---------------------------------------------------

 

 

ここまで