我欢迎一些C ++继承方面的帮助,以便更好地掌握这个概念。 是否有可能扩展"创建派生类时的成员类型?我认为我的问题可以通过一个简单的例子得到最好的证明,我想用新的双变量扩展类 VehicleData :
class VehicleData {
int yearOfManufacture;
//Different routines, for example Serialize(), etc., warranting to create a class for just a bunch of variables
};
class BicycleData:VehicleData {
double frameHeight; //new property that only applies to bicycles
};
//Now I create the actual classes that use the types above
class Vehicle {
VehicleData data;
void PrintData(); //a function that works on basic vehicle data
};
class Bicycle:Vehicle {
BicycleData data; //should copy VehicleData when creating an instance of this class
};
这种方法的问题在于,当我对上面的代码进行编码并创建一个Bicycle实例时,其BicycleData成员隐藏了现有的VehicleData成员。
有没有办法扩展基类,即只需添加一个新的双变量(在此示例中存储帧高度),并保留已存在的(制造年份)数据? / p>
答案 0 :(得分:1)
简短回答;不是你想要的方式,但你可以达到类似的目的。
如果您将数据作为指针,则不要声明您拥有的实例。然后,您可以让BicycleData继承VehicleData,然后只需将数据替换为Bicycle的构造函数中的新实例。
即
class Vehicle {
void PrintData();
protected:
void replaceData(std::shared_ptr<VehicleData> d) {
data = d;
}
std::shared_ptr<VehicleData> getData() {
return data;
}
template<class T>
std::shared_ptr<T> getDataAs() {
return std::dynamic_pointer_cast<T>(data);
}
private:
std::shared_ptr<VehicleData> data;
};
class Bicycle:Vehicle {
Bicycle(){replaceData(std::make_shared<BicycleData>());}
std::shared_ptr<BicycleData> getData() {
return getDataAs<BicycleData>();
}
};
答案 1 :(得分:1)
据我所知,没有干净的方法可以完全你想要的只有继承。
您可以从基类中创建模板:
template <typename Data>
class BaseVehicle
{
Data data;
// etc.
};
class Vehicle : BaseVehicle<VehicleData>
{
// etc.
};
class Bicycle : BaseVehicle<BicycleData>
{
// etc.
};
然后,Vehicle
和Bicycle
类将分别包含data
和VehicleData
类型的BicycleData
字段。
因为在您的示例中,Bicycle
从Vehicle
私下继承(即不支持通过指针/引用Bicycle
多态地使用Vehicle
}),这实际上与你想要达到的目标相同。
如果你做想要动态多态,你应该创建一个单独的,最好是抽象的类,为你的车辆定义接口,例如:
class VehicleInterface
{
public:
// Some pure virtual interface methods
virtual void moveTo(const Vector2 position) = 0;
virtual ~VehicleInterface() = default;
};
然后你可以让你的混凝土车辆继承并实现这个界面:
class Vehicle : BaseVehicle<VehicleData>, public VehicleInterface
{
public:
virtual void moveTo(const Vector2 position) override
{
// implementation for Vehicle
}
};
class Bicycle : BaseVehicle<BicycleData>, public VehicleInterface
{
public:
virtual void moveTo(const Vector2 position) override
{
// implementation for Bicycle
}
};
然后,任何希望以多态方式使用车辆的函数都可以接受引用或指向VehicleInterface
的指针:
void driveToWork(VehicleInterface* vehicle)
{
vehicle->moveTo(getWorkPosition());
// etc.
}