通过未被覆盖的基类从派生类调用函数

时间:2012-12-03 01:04:04

标签: c++ inheritance

在C ++中;

有没有办法通过基类从派生类调用函数 即使功能没有被覆盖?换句话说,我正在使用基类 为了拥有异构容器而没有提升;我想调用一个成员函数 这只是派生类...

实施例: (我刚刚编写了这段代码,因此可能存在语法错误,但希望您能获得要点)

class Vehicle
{
  public:
   virtual void do_vehicle_stuff();
   // virtual void do_car_specific_stuff(); makes no sense here
}

class Car : public Vehicle
{
  public:
   void do_vehicle_stuff();
   void do_car_specific_stuff();
}

Car a,b;

list<Vehicle> vehicle_list;
vehicle_list.push_back(a);
vehicle_list.push_back(b);

vehicle_list.front().do_car_specific_stuff();

错误:'Class Vehicle'没有名为'do_car_specific_stuff()'的成员

2 个答案:

答案 0 :(得分:1)

当您将类插入列表时,您正在对它们进行切片。在 C ++子类型多态性(您正在使用的多态性类型) 通过引用或指针工作但不是值。当你插入 将carS list转换为VehicleS,将其转换为Car c; std::vector<Vehicle> vs; vs.push_back(c); // slicing happens vs.front(); // not a car anymore, but just a vehicle, // the Car-ness is lost through the copy operation

一个例子:

std::vector<std::unique_ptr<Vehicle>> vs;
vs.push_back(new Car());
vs.front(); // actually a Car

怎么做:

Vehicle* vehiclep = new Car();
if(auto carp = dynamic_cast<Car*>(vehiclep)) {
  carp->do_car_specific_stuff();
}

解决了代码的根本缺陷后,可能会这样做 帮助你:

{{1}}

这是一项相当昂贵的操作,并且通常表示a 设计气味,所以你可能想重新思考你在做什么。

答案 1 :(得分:1)

这是一个更合适的设计:

struct Vehicle
{
    virtual ~Vehicle() { }

    void do_vehicle_stuff()
    {
        vehicle_impl();
    }

private:
    virtual void vehicle_impl() = 0;
};

struct Car : Vehicle
{
private:
    virtual void vehicle_impl()
    {
        my_vehicle_stuff();
        my_car_specific_stuff();
    }

    void my_vehicle_stuff()      { /* what you had originally */ }
    void my_car_specific_stuff() { /* car-only stuff */ }
};

std::list<std::unique_ptr<Vehicle>> vehicles;

vehicles.emplace_back(new Car);
vehicles.emplace_back(new Motorcycle);
vehicles.emplace_back(new Carriage);
相关问题