C ++ полиморфизм с бустом scoped_ptr - PullRequest
3 голосов
/ 23 марта 2012

Почему следующий код не позволяет вызывать foo (ptr)?

#include <boost/scoped_ptr.hpp>
struct A {
    virtual ~A() {}
};

struct B: public A {};

void foo(boost::scoped_ptr<A>& a) {}

void goo(A& a) {}
int main() {
    boost::scoped_ptr<B> ptr(new B);
    foo(ptr);
    B b;
    goo(b);
}

Соответствующая форма, где мы передаем ссылки, работает, как ожидалось. Разве мы не должны заниматься полиморфизмом? с бустом scoped_ptr?

g ++ с надстройкой 1.49 дает мне:

error: invalid initialization of reference of type ‘boost::scoped_ptr<A>&’ from expression of type ‘boost::scoped_ptr<B>’

1 Ответ

5 голосов
/ 23 марта 2012

Это потому, что foo по какой-то причине принимает указатель с областью действия по ссылке . Это совершенно не нужно и является причиной сбоя вызова. Существует преобразование из scoped_ptr<B> в scoped_ptr<A>, но не из scoped_ptr<B>& в scoped_ptr<A>&.

Вы должны передать его как ссылку на const.

void foo(boost::scoped_ptr<A> const & a) {}

Кстати, это не «проблема» умных указателей как таковых. Следующий код не работает по тем же причинам, что и ваш.

void foo(A*& p) {}
int main()
{
    B* p = new B;
    foo(p); //FAIL
}

Чтобы исправить это, вы должны передать указатель либо по значению, либо, если вы достаточно извращены, по ссылке на const

 void foo (A * const & p); // <-- a perv wrote this
...