2016-12-10 47 views
3

我有一個基類和兩個派生類的繼承層次結構。基於繼承類型參數改變父虛擬函數的行爲

在基類,我有一個虛擬函數:

virtual void interact(const Base &other) const; 

在派生類,它們都具有以下兩種功能,因爲這兩個派生類相互作用彼此不同,其是必要的(即Derived1Derived1相互作用不同於Derived1Derived2):

void interact(const Derived1 &other) const; 
void interact(const Derived2 &other) const; 

我希望能夠從vector<Base>採取兩個對象,並調用VI實例Base類方法(例如, base1.interact(base2)),並根據派生類型在派生類中調用正確的函數。

有沒有一種方法可以做到這一點,或者我的方法完全錯誤?

+0

該技術被稱爲「雙調度」,有各種實現。 –

+0

同一個向量中的兩個對象顯然是相同的類型(向量的定義)。要「能夠從矢量中獲取兩個對象」很容易,但它們都是相同的類型。這似乎不是你的計劃。我建議不要投下來。 –

回答

3

有沒有辦法我可以做到這一點,或者我的做法是完全錯誤的嗎?

您正在查找的技術被稱爲雙派遣
這不是完全錯誤。作爲一個例子,模式訪客建立在相同的概念之上。

它遵循基於你的問題的細節最小,工作示例:

#include<iostream> 

struct Derived1; 
struct Derived2; 

struct Base { 
    virtual void interact(const Base &) const = 0; 
    virtual void interact(const Derived1 &) const = 0; 
    virtual void interact(const Derived2 &) const = 0; 
}; 

struct Derived1: Base { 
    void interact(const Base &other) const override { 
     other.interact(*this); 
    } 

    void interact(const Derived1 &) const { 
     std::cout << "Derived1/Derived1" << std::endl; 
    } 

    void interact(const Derived2 &) const { 
     std::cout << "Derived2/Derived1" << std::endl; 
    } 
}; 

struct Derived2: Base { 
    void interact(const Base &other) const override { 
     other.interact(*this); 
    } 

    void interact(const Derived1 &) const { 
     std::cout << "Derived1/Derived2" << std::endl; 
    } 

    void interact(const Derived2 &) const { 
     std::cout << "Derived2/Derived2" << std::endl; 
    } 
}; 

void foo(const Base &lhs, const Base &rhs) { 
    lhs.interact(rhs); 
} 

int main() { 
    foo(Derived1{}, Derived1{}); 
    foo(Derived1{}, Derived2{}); 
    foo(Derived2{}, Derived1{}); 
    foo(Derived2{}, Derived2{}); 
} 

它要求所有的interact方法是虛擬和基礎類的一部分。
其基本思想是,對Base的引用作爲參數傳遞給的類推廣並將其自身用作(讓我說)標記將請求正確地分派給正確的方法。
它通過回調調用者並將其作爲函數參數傳遞給自己。