【发布时间】:2016-01-05 18:34:21
【问题描述】:
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() {}
}
所有状态都是从 BaseState 派生的,因此它们具有成员变量 mVehicle 来访问外部类变量。 但是,在每个派生类中,在每个State的所有函数中,都需要static_cast来访问派生类的成员变量和函数。
有更好的解决方案吗?
- 在派生类的每个状态中,添加另一个指针(例如,Convertible *mConvertible)。每个状态都有重复的指针(mConvertible 和 mVehicle)指向同一个对象。看起来不对。
- 在基类中使用虚拟 Getter 而不是 mVehicle。基类中会有过多的 Getter 调用。
================================================ =========================
是的。我尝试了下面的模板,但它无法编译,因为像
这样的错误“car.h:在成员函数‘virtual void Car::State1::run()’中: car.h:18:12:错误:“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::State1::processEvent(),为什么不能自动将mVehicle从Car*转换为Convertible*?显然mVehicle 在推导Convertible::State1::processEvent() 时指向Convertible 对象。如果有自动转换,我们不需要模板。
【问题讨论】:
-
模板。使用它们。
-
能否提供更多信息?
标签: c++ templates inheritance polymorphism