我已经看过几个关于这个主题的帖子,但没有找到我想要的那种解决方案。对于另一个重复,一开始很抱歉。但我想知道你的专家在面对下面给出的情况时会做些什么?
class Vehicle // A base class
{
public:
static Vehicle* CreateInstance(const int createWhat)
{
switch(createWhat)
{
case 1:
return new Segway();
break;
case 2:
return new Car();
break;
}
}
};
现在我有几个派生类..
class Segway : public Vehicle // Segway is a vehicle
{
};
class Sensor
class FuelConsumptionInfo;
class Car : public Vehicle // Car is a vehicle
{
public:
std::list<Sensor>& GetSensorList()
{
return m_pListOfSensors;
}
bool CompareThisCarAgainstOthers(std::list<Vehicle*>& vehicles) const
{
bool isMostEfficientCar = false;
std::list<Vehicle*>::iterator iterVal = vehicles.begin();
while(iterVal != vehicles.end())
{
// 1. Get the list of sensors of this car and compare against the sensors of this car ...
// 2. Get the fuel consumption information and compare against the fuel efficiency of this car ...
}
return isMostEfficientCar;
}
private:
std::list<Sensor*> m_pListOfSensors;
FuelConsumptionInfo* m_FuelEfficiency;
};
最后我有我最喜欢的车和其他一些车,我想把我的车与他们比较。
int main()
{
std::list<Vehicle*> listOfOtherCars;
Vehicle* pMyFavCar = Vehicle::CreateInstance(2);
listOfOtherCars.push_back(Vehicle::CreateInstance(2));
listOfOtherCars.push_back(Vehicle::CreateInstance(2));
listOfOtherCars.push_back(Vehicle::CreateInstance(2));
listOfOtherCars.push_back(Vehicle::CreateInstance(2));
// How can I invoke the CompareThisCarAgainstOthers without:
// 1. Introducing any base class empty functions ..
// 2. Without using static/dynamic casting to convert the base pointer to a derived class pointer ...
}
正如评论中已经提到的,我想调用 CampareThisCarAgainstOthers ,但我不想转换基类指针,也不想在基类中引入任何虚函数我认为违背了拥有基类的整个逻辑。即使引入空虚拟基本函数也无济于事,因为 GetSensorList 会返回对列表的引用。
我将非常感谢你的回答。
答案 0 :(得分:1)
使用基指针访问子方法的唯一方法是将基指针强制转换为子指针。这有不好的副作用(在互联网上搜索&#34; C ++对象切片&#34;)。
一个问题是你不知道基指针指向的是什么类型的子/对象。您可以将指针强制转换为错误的子方法。示例:指向Cruise Ship的指针被传递给一个带有指向车辆的指针的函数。在函数内部会发生什么,指针会转换为Bicycle
类型。显然,不是同一辆车。
使用指向基类的指针可以安全访问的是公共方法和基类的成员。不多也不少。
例如,给定基类Car
和一些子类,如Model_T
,Tesla
,Hybrid
和Mustang
,以及指向一个Car
个例子,你不知道这个孩子是什么样的车。 Model_T
与电Tesla
不同。带有汽油发动机的Mustang
与带有电动和汽油发动机的Hybrid
不同。
如果要使用基类指针访问功能,请将功能作为抽象函数放入基类中。 Car
类可以有方法virtual bool has_electric_engine(void) const = 0;
。 Model_T
和Mustang
将返回false
。
请不要将虚拟相等方法转换为基类,因为代码将比较属性,但您确实想要比较类型。在示例中,Mustang
汽车与Model_T
没有完全相同的属性。通常,如果您需要比较类型,您的设计是有缺陷的。