Можно ли сделать shared_ptr ковариантным? - PullRequest
1 голос
/ 19 февраля 2020

Я попытался сделать следующий пример.

struct BaseSPtr{};
struct DerivedSPtr : public BaseSPtr{};


class Base{
    public:
    //virtual shared_ptr<BaseSPtr> function();
    virtual BaseSPtr* function();    
};

class Derived : public Base
{
    public:
    //shared_ptr<DerivedSPtr> function() override;
    DerivedSPtr* function() override;
};

Может кто-нибудь сказать мне, возможно ли сделать пример с shared_ptr допустимым?

Ответы [ 2 ]

3 голосов
/ 19 февраля 2020

К сожалению, нет, ковариация применяется только к указателям и ссылкам в C ++.

Чтобы иметь похожий интерфейс, вы должны сделать что-то вроде:

class Base{
public:
    std::shared_ptr<BaseSPtr> function() { return std::shared_ptr<BaseSPtr>(function_v()); }
private:
    virtual BaseSPtr* function_v();
};

class Derived : public Base
{
public:
    std::shared_ptr<DerivedSPtr> function() // Hides Base::function
    {
        return std::shared_ptr<DerivedSPtr>(function_v());
    }
private:
    DerivedSPtr* function_v() override; // Overrides Base::function_v
};

CRTP может помочь уменьшить дублирование .

0 голосов
/ 19 февраля 2020

Теперь вопрос в том, как вы используете Derived класс?

  • вы используете его явно, и polymorphi c вызов function() не выполняется?
  • или делаете вы храните эту фабрику в некотором хранилище, и function() вызывается полиморфно c way
  • или вы используете это в некоторых шаблонах

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

Во втором случае вам не следует пытаться убедить компилятор, что вы возвращаете производный класс, так как вызов polymorphi c будет скрывать это все равно.

В последнем случае просто используйте CRTP в качестве другого предложенного ответа (некоторые называют это полиморфизмом stati c) и отбросьте виртуальное ключевое слово.

...