2012-12-03 154 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);