1

在 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();

错误:“类车辆”没有名为“do_car_specific_stuff()”的成员

4

2 回答 2

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();
}

这是一项相当昂贵的操作,通常表明设计有异味,因此您可能需要重新考虑您在做什么。

于 2012-12-03T01:11:53.853 回答
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);
于 2012-12-03T01:15:12.947 回答