2012-12-03 115 views
0

in 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)(”

+0

这可能帮助:http://stackoverflow.com/questions/28002/regular-cast-vs-static-cast-vs-dynamic-cast – chris

+3

当然,它要抽象的东西来了解具体事情的细节是没有意义的? –

+0

我知道下面的pmr片段切片,但无法找到一个适当的解决方法.. – user1871298

回答

0

没有成员,当你将它们插入到列表中你是切片你的类。在 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(); 
} 

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

+0

好!相信我,我正在重新思考这是如何实现的:) – user1871298

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