【问题标题】:Polymorphic dispatch using boost::shared_ptr使用 boost::shared_ptr 的多态调度
【发布时间】:2013-07-07 02:45:20
【问题描述】:

我正在尝试根据向量中指针的派生类型调用重载函数。

我有一个基类 Fruit,并创建一个 shared_ptr 向量。然后我将后代的共享指针推送到向量中。到目前为止,一切都很好(问题出现在我添加代码以打印元素之后)。

接下来,我想遍历容器,为每个水果调用适当的 Print 函数。我收到编译错误:

# 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 上,在 Cygwin 下使用 g++:

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

我希望在调用时调用Print_via_ptr(boost::shared_ptr&lt;Apple&gt;)

Print_via_ptr(bowl[0]);

【问题讨论】:

  • bowlFruit* 的向量,而不是shared_ptr&lt;Apple&gt; 的向量。编译器应该如何知道bowl[0]Apple,为什么你认为它会自动将其转换为shared_ptr&lt;Apple&gt;

标签: c++ vector polymorphism shared-ptr dispatch


【解决方案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&lt;Fruit&gt; 而不是 boost::shared_ptr&lt;Apple&gt;

它们只能被调用

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-05
    • 1970-01-01
    • 1970-01-01
    • 2012-11-24
    • 1970-01-01
    相关资源
    最近更新 更多