- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
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() {}
}
所有States都是从BaseState派生出来的,所以它们都有成员变量mVehicle来访问外部类变量。但是,在每个派生类中,在每个State的所有函数中,都需要static_cast来访问派生类的成员变量和函数。
有更好的解决方案吗?
============================================= ========================
是的。我试过下面的模板,但它无法编译,因为像
这样的错误"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
Convertible::State1::processEvent()
时的对象被推导出来。如果有自动转换,我们不需要模板。
最佳答案
使用模板。
从 Car
中删除指针内部类(使它们成为充满纯虚函数的抽象类)。
添加新模板类 CarT
(或考虑更好的名字)
template <typename T>
class CarT {
class CarHolder {
explicit CarHolder(T* car) : car(car) {}
T* car;
};
class State1 : public Car::State1, protected CarHolder {
explicit State1(Car* vehicle) : CarHolder(vehicle) {}
virtual void run() {
// use data of Car
...
doSomething();
}
virtual void doSomething() {
}
};
class State2 : public Car::State2 {
};
...
};
这样你将拥有 Car
的运行时多态性它是 State
的和良好的派生类编译时多态性(这反过来将消除对丑陋 static_cast
的需求)
class Convertible: public CarT<Convertible> {
typename CarT<Convertible> Base;
class State1 : public Base::State1 {
explicit State1(Convertible* vehicle) : Car::State1(vehicle) {}
virtual void doSomething() {
car->foldTop();
}
}
class State2 : public Base::State2 {
}
...
void foldTop() {}
}
class Convertible : public CarT<Convertible>
可能看起来很奇怪,但它会起作用(CarT
仅将模板参数用作指针,如果将其用作值成员,则可能会出现一些问题)
关于c++ - 在虚函数中访问派生类成员变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33010677/
我有一个特别的问题想要解决,我不确定是否可行,因为我找不到任何信息或正在完成的示例。基本上,我有: class ParentObject {}; class DerivedObject : publi
在我们的项目中,我们配置了虚 URL,以便用户可以在地址栏中输入虚 URL,这会将他们重定向到原始 URL。 例如: 如果用户输入'http://www.abc.com/partner ',它会将它们
我是一名优秀的程序员,十分优秀!