Ковариантные виртуальные функции и умные указатели - PullRequest
8 голосов
/ 12 июля 2009

В C ++ подкласс может указать другой тип возвращаемого значения при переопределении виртуальной функции, если возвращаемый тип является подклассом исходного возвращаемого типа (и оба возвращаются как указатели / ссылки).

Можно ли расширить эту функцию и на умные указатели? (Предполагается, что умный указатель - это некоторый класс шаблона)

Для иллюстрации:

class retBase {...};
class retSub : public retBase {...};

class Base
{
    virtual retBase *f();
};

class Sub : public Base
{
    virtual retSub *f();     // This is ok.
};


class smartBase
{
    virtual smartPtr<retBase> f();
};

class smartSub : public smartBase
{
    virtual smartPtr<retSub> f();     // Can this be somehow acheived?
};

РЕДАКТИРОВАТЬ: Как предположил Конрад Рудольф, это невозможно напрямую. Однако я столкнулся с этим методом:

class smartBase
{
    protected:
        virtual retBase *f_impl();
    public:
        smartPtr<refBase> f()
        {
             return f_impl();
        }
};

class smartSub : public smartBase
{
    protected:
        virtual retSub *f_impl();
    public:
        smartPtr<refSub> f()
        {
             return f_impl();
        }
};

Вы бы предложили пойти по этому пути?

Ответы [ 2 ]

8 голосов
/ 12 июля 2009

Можно ли расширить эту функцию и на умные указатели? (Предполагается, что умный указатель - это некоторый класс шаблона)

Нет: C ++ не знает / не допускает ковариантные или контравариантные шаблоны. Между типами Ptr<A> и Ptr<B> нет никакой связи, даже если A наследуется от B.

0 голосов
/ 26 июля 2010

Boost shared_ptr может содержать полиморфный указатель. Если вам нужен ковариантный тип возвращаемого значения, то вы хотите использовать что-то определенное для подтипа. В этом случае вы можете оставить тип возвращаемого значения без изменений и использовать dynamic_pointer_cast для понижения указателя.

...