通过基类引用进行迭代时,有没有一种方法可以调用派生类方法?

时间:2018-11-30 14:40:44

标签: c++

我有一个基类images: state.images.filter(img => img !== image)和几个派生类,例如Auto_Partclass Batteryclass Engine等。我还有一个孙子派生的class Frame继承所有派生的零件类。

我的目标:我有一个class Car和一个清单对象Inventory class。第一个值是要存储的Auto_Part引用,第二个值是库存中有多少个可用。 用户应该能够使用库存中可用的零件来创建汽车对象。我想遍历此地图并使用适当的访问器方法来获取创建我的汽车对象所需的数据。 >

这是有问题的功能。我正在尝试使用MVC模型,因此它是Controller函数。

map<Auto_Part*, int>

}

因此void Controller::add_car_from_parts(){ //All variables used in all of the parts std::string type, frame_type, category, color, bolt_pattern, tire_type, speed_rating,load_range, w_frame_type; std::string name, fuel_type, grip_type, horn_type, display_color, seat_material, seat_warmers, door_material, butterfly_doors; int part_number, cranking_amps, cold_cranking_amps, voltage,diameter,width,ratio, w_diameter,w_width, num_doors, length,reserve_capacity_minutes,num_cylinders, steering_wheel_diameter, num_seats, display_length; double price; int quantity; Dialogs::message("You will be shown the parts available in the inventory. Please write down the part number of the part you will add to you vehicle.", "PART NUMBER"); view.view_all_inventory(); part_number = view.pn_prompt(); //quantity = view.quantity_prompt(); for(auto x: inventory.get_inventory()){ //inventory is a map<Auto_Part*,int> if (x.first->get_part_number() == part_number){ // If part is in the inventory if (x.first->get_type() == "Battery"){// and if the part is a battery, auto_part function available in all auto_part classes including class Auto_Part name = x.first->get_name(); // auto_part function, available in all auto_part classes including class Auto_Part price = x.first->get_price(); // auto_part function, available in all auto_part classes including class Auto_Part cranking_amps = x.first->get_cranking_amps(); // battery function only cold_cranking_amps = x.first->get_cold_cranking_amps(); // battery function only voltage = x.first->get_voltage(); // battery function only reserve_capacity_minutes = x.first->get_reserve_capacity_minutes(); //battery function only inventory.remove_parts(x.first,1); // removes part from inventory, second value is quantity removed } } } x.first->get_part_number()x.first->get_type()x.first->get_name()可以正常工作,因为它们在Auto_Part类以及所有派生类中,因此在进行迭代时通过它指向适当的get函数。 第一个错误是在x.first->get_price()行,我的编译器说“ Auto_Part类没有get_cranking_amps()函数,只有电池功能。”

我认为,由于地图是由cranking_amps = x.first->get_cranking_amps()而不是Auto_Part*对象组成的,因此它将引用适当的类。就像在x中一样,x在遍历映射到Battery对象或Engine对象时会有所变化,具体取决于它是什么,因此我可以使用其独特的功能。 在遍历此基类引用列表时如何调用派生类函数?当然,我不需要在基类中创建每个派生类函数,对吗?看来这将破坏具有唯一功能的派生类的目的。

谢谢您的时间。

1 个答案:

答案 0 :(得分:0)

编译器不知道get_type() == "Battery"class Battery有任何关系。您仍然只有Auto_Part*

如果要使用通过Auto_Part*无法访问的成员,则必须使用强制转换自己进行类型转换:

auto superclass = x.first;
if (superclass->get_type() == "Battery") {
        name = superclass->get_name();
        price = superclass->get_price();
        Battery* subclass = static_cast<Battery*>(parent);
        cranking_amps = subclass->get_cranking_amps();
        cold_cranking_amps = subclass->get_cold_cranking_amps();
        voltage = subclass->get_voltage();
        reserve_capacity_minutes = subclass->get_reserve_capacity_minutes();
        inventory.remove_parts(superclass,1);
    }

但是,当使用类型系统时,您甚至不需要get_type()函数,就可以使用运行时类型检查:

auto superclass = x.first;
auto as_battery = dynamic_cast<Battery*>(superclass);
if (as_battery) {
        name = superclass->get_name();a
        price = superclass->get_price();
        cranking_amps = as_battery->get_cranking_amps();
        cold_cranking_amps = as_battery->get_cold_cranking_amps();
        voltage = as_battery->get_voltage();
        reserve_capacity_minutes = as_battery->get_reserve_capacity_minutes();
        inventory.remove_parts(superclass,1);
    }

如果运行时类型不匹配,dynamic_cast将得出空指针。

正如@davidbak所说,Visitor模式旨在以更可维护的方式解决此问题(尽管前面有更多代码)。