2013-07-07 67 views
0

我想基於向量中的指針派生類型調用重載函數。使用boost :: shared_ptr的多態派發

我有一個基類Fruit,並創建了一個shared_ptr向量。然後,我將共享的後代指向推向矢量。到目前爲止,這麼好(在我添加代碼打印元素後,問題就出現了)。

接下來,我想遍歷容器,爲每個水果調用適當的打印函數。我收到編譯錯誤:

# g++ -I/cygdrive/c/Program\ Files/boost/boost_1_52_0 -o main.exe main.cpp 
main.cpp: In function `int main()': 
main.cpp:80: error: no matching function for call to `Print_via_ptr(const boost::shared_ptr<Fruit>&)' 
main.cpp:57: note: candidates are: void Print_via_ptr(boost::shared_ptr<Apple>) 
main.cpp:58: note:     void Print_via_ptr(boost::shared_ptr<Orange>) 
main.cpp:59: note:     void Print_via_ptr(boost::shared_ptr<Strawberry>) 
main.cpp:95: error: no matching function for call to `Print(Fruit&)' 
main.cpp:53: note: candidates are: void Print(const Apple&) 
main.cpp:54: note:     void Print(const Orange&) 
main.cpp:55: note:     void Print(const Strawberry&) 

下面是代碼:

#include <iostream> 
#include <string> 
#include <cstdlib> 
#include <vector> 
#include "boost/shared_ptr.hpp" 

using std::cout; 
using std::cin; 
using std::endl; 


struct Fruit 
{ 
    virtual const std::string&  who_am_i(void) const = 0; 
}; 


struct Apple 
    : public Fruit 
{ 
    const std::string& who_am_i(void) const 
     { 
      static const std::string name = "Apple"; 
      return name; 
     } 
}; 


struct Orange 
    : public Fruit 
{ 
    const std::string& who_am_i(void) const 
     { 
      static const std::string name = "Orange"; 
      return name; 
     } 
}; 


struct Strawberry 
    : public Fruit 
{ 
    const std::string& who_am_i(void) const 
     { 
      static const std::string name = "Strawberry"; 
      return name; 
     } 
}; 


void Pause(void); 

void Print(const Apple& a); 
void Print(const Orange& o); 
void Print(const Strawberry& s); 

void Print_via_ptr(boost::shared_ptr<Apple> p_a); 
void Print_via_ptr(boost::shared_ptr<Orange> p_o); 
void Print_via_ptr(boost::shared_ptr<Strawberry> p_s); 


int main(void) 
{ 
    std::vector<boost::shared_ptr<Fruit> > basket; 
    boost::shared_ptr<Apple>  p_apple(new Apple); 
    boost::shared_ptr<Orange>  p_orange(new Orange); 
    boost::shared_ptr<Strawberry> p_strawberry(new Strawberry); 

    // Put fruit into basket. 
    basket.push_back(p_apple); 
    basket.push_back(p_orange); 
    basket.push_back(p_strawberry); 

    // Display the basket of fruit shared_ptr 
    cout << "Basket contents:\n"; 
    for (std::vector<boost::shared_ptr<Fruit> >::const_iterator iter = basket.begin(); 
     iter != basket.end(); 
     ++iter) 
    { 
     Print_via_ptr(*iter); // Line 80 
    } 

    // Create bowl of fruit pointers 
    std::vector<Fruit *> bowl; 
    bowl.push_back(new Apple); 
    bowl.push_back(new Orange); 
    bowl.push_back(new Strawberry); 

    // Print the fruit. 
    std::vector<Fruit *>::const_iterator bowl_iter; 
    for (bowl_iter = bowl.begin(); 
     bowl_iter != bowl.end(); 
     ++bowl_iter) 
    { 
     Print(**bowl_iter); // Line 95 
    } 

    Pause(); 

    return EXIT_SUCCESS; 
} 


void 
Pause(void) 
{ 
    cout << "Paused. Press Enter to continue.\n"; 
    cin.ignore(10000, '\n'); 
} 


void 
Print(const Apple& a) 
{ 
    cout << a.who_am_i() << endl; 
} 


void 
Print(const Orange& o) 
{ 
    cout << o.who_am_i() << endl; 
} 


void 
Print(const Strawberry& s) 
{ 
    cout << s.who_am_i() << endl; 
} 


void 
Print_via_ptr(boost::shared_ptr<Apple> p_a) 
{ 
    cout << p_a->who_am_i() << endl; 
} 


void 
Print_via_ptr(boost::shared_ptr<Orange> p_o) 
{ 
    cout << p_o->who_am_i() << endl; 
} 


void 
Print_via_ptr(boost::shared_ptr<Strawberry> p_s) 
{ 
    cout << p_s->who_am_i() << endl; 
} 

我在Windows Vista上,使用G ++在Cygwin下:

# g++ --version 
g++ (GCC) 3.4.4 (cygming special, gdc 0.12, using dmd 0.125) 

我想Print_via_ptr(boost::shared_ptr<Apple>)時調用我援引:

Print_via_ptr(bowl[0]); 
+0

'碗'是'水果*'矢量不是'shared_ptr '的矢量。編譯器應該如何知道'bowl [0]'是'Apple',爲什麼你會認爲它會自動將它轉換爲'shared_ptr '? –

回答

1

多態調度是通過基指針或引用類型完成的,它不會自動轉換爲派生指針/引用類型。

std::vector<boost::shared_ptr<Fruit> > basket; 
boost::shared_ptr<Apple> p_apple(new Apple); 
basket.push_back(p_apple); 

當你調用push_back,對象與原始指針函數存儲爲boost::shared_ptr<Fruit>沒有boost::shared_ptr<Apple>

通過

void Print_via_ptr(const boost::shared_ptr<Fruit> p_a); 
              ^^^^^ 

同樣的問題,他們只能被調用。

或者您可以使用模板爲您生成呼叫,但這可能不是您的目的。

template<typename T> 
void Print_via_ptr(T p_o) 
{ 
    std::cout << p_o->who_am_i() << std::endl; 
} 
相關問題