class Car {
class BaseState {
explicit BaseState(Car* vehicle) : mVehicle(vehicle) {}
virtual void run() = 0;
Car* mVehicle;
}
class State1 : public BaseState {
explicit State1(Car* vehicle) : BaseState(vehicle) {}
virtual void run() {
// use data of Car
...
doSomething();
}
virtual void doSomething() {
}
}
class State2 : public BaseState {
}
...
}
class Convertible: public Car {
class State1 : public Car::State1 {
explicit State1(Convertible* vehicle) : Car::State1(vehicle) {}
virtual void doSomething() {
static_cast<Convertible*>(mVehicle)->foldTop();
}
}
class State2 : public Car::State2 {
}
...
void foldTop() {}
}
すべての状態は、外部クラス変数にアクセスするメンバー変数mVehicleを持つように、BaseStateから派生しています。 しかし、各派生クラスでは、各状態のすべての関数において、派生クラスメンバ変数と関数にアクセスするにはstatic_castが必要です。仮想関数内の派生クラスメンバー変数へのアクセス
もっと良い解決策はありますか?
- 派生クラスの各状態では、別のポインタ(Convertible * mConvertibleなど)を追加します。各ステートには同じオブジェクトを指す重複ポインタ(mConvertibleとmVehicle)があります。見えません。
- ベースクラスでmVehicleの代わりに仮想ゲッターを使用します。ベースクラスにはゲッターコールが過剰になります。
============================================ =============================
はい。私は以下のようにテンプレートを試しましたが、エラーのようにエラーが発生したため、コンパイルできません。
"car.h:メンバー関数で 'virtual void Car :: State1 :: run()': car.h:18:12:error : 'mVehicle'はこのスコープで宣言されていません "
// car.h
#include <iostream>
template <class T>
class Car {
public:
class BaseState {
public:
explicit BaseState(T* vehicle) : mVehicle(vehicle) {}
protected:
T* mVehicle;
};
class State1 : public BaseState {
public:
explicit State1(T* vehicle) : BaseState(vehicle) {}
virtual void run() {
mVehicle->x = 1;
mVehicle->y = 2;
mVehicle->doSomething1();
mVehicle->doSomething2();
processEvent();
}
virtual void processEvent() {
if (mVehicle->val > 2) {
std::cout << "too large" << std::endl;
}
}
};
class State2 : public BaseState {
public:
explicit State2(T* vehicle) : BaseState(vehicle) {}
virtual void run() {
mVehicle->x = 10;
mVehicle->y = 20;
processEvent();
}
virtual void processEvent() {
if (mVehicle->val > 20) {
std::cout << "too large" << std::endl;
}
}
};
virtual void doSomething1() {
val += x * y;
}
virtual void doSomething2() {
val += x + y;
}
protected:
int x;
int y;
int val;
};
// convertible.h
#include "car.h"
#include <iostream>
class Convertible : public Car<Convertible> {
protected:
class State1 : public Car<Convertible>::State1 {
explicit State1(Convertible* vehicle) : Car<Convertible>::State1(vehicle) {}
// want to override functions in base class states
virtual void processEvent() {
if (mVehicle->val > 10) {
std::cout << "too large" << std::endl;
mVehicle->val = 10;
}
}
};
// want to override some base class functions
// and access some special variables
// want to inherit other functions
virtual void doSomething2() {
z = 10;
val += x + y + z;
}
protected:
int z;
};
私はState1(Car* vehicle)
代わりのState1(T* vehicle)
使用する場合は、追加の変換エラーが発生しました。私は間違って何をしていますか?
プログラムが自動的にConvertible*
にCar*
からmVehicle
をキャストできない理由Convertible::State1::processEvent()
は、実行する必要があることを把握することができますか? Convertible::State1::processEvent()
が推定されるConvertible
オブジェクトへどうやらmVehicle
ポイント。自動キャストがあればテンプレートは必要ありません。
テンプレート。それらを使用してください。 –
詳細をお知らせください。 – dekst
答えを見てください。 –