Полиморфная диспетчеризация с использованием boost :: shared_ptr

Я пытаюсь вызвать перегруженные функции на основе производного типа указателя в векторе.

У меня есть базовый класс, 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, используя 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

Решение

Полиморфная диспетчеризация осуществляется через базовый указатель или ссылочный тип, он не приводится автоматически к производному указателю / ссылочному типу.

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

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]