如何在C++中返回智能指针和协方差

问题描述 投票:0回答:1

我正在关注本教程以了解如何在 C++ 中返回智能指针和协方差。

  #include <memory>
  #include <iostream>

  class cloneable
  {
  public:
     virtual ~cloneable() {}

     std::unique_ptr<cloneable> clone() const
     {
        return std::unique_ptr<cloneable>(this->clone_impl());
     }

  private:
     virtual cloneable * clone_impl() const = 0;
  };
   
  ///////////////////////////////////////////////////////////////////////////////

  template <typename Derived, typename Base>
  class clone_inherit: public Base
  {
  public:
     std::unique_ptr<Derived> clone() const
     {
        return std::unique_ptr<Derived>(static_cast<Derived *>(this->clone_impl()));
     }

  private:
     virtual clone_inherit * clone_impl() const override
     {
        return new Derived(*this); // getting error here 
     }
  };


  class concrete : public clone_inherit<concrete, cloneable>
  {
    
  };

  int main()
  {
    std::unique_ptr<concrete> c = std::make_unique<concrete>();
  }

当我执行此示例时,出现以下错误:

  /tmp/0RmVdQYjfA.cpp: In instantiation of 'clone_inherit<Derived, Base>* clone_inherit<Derived, Base>::clone_impl() const [with Derived = concrete; Base = cloneable]':
  /tmp/0RmVdQYjfA.cpp:30:28:   required from here
  /tmp/0RmVdQYjfA.cpp:32:14: error: no matching function for call to 'concrete::concrete(const clone_inherit<concrete, cloneable>&)'
     32 |       return new Derived(*this);
        |              ^~~~~~~~~~~~~~~~~~
  /tmp/0RmVdQYjfA.cpp:37:7: note: candidate: 'constexpr concrete::concrete()'
     37 | class concrete : public clone_inherit<concrete, cloneable>
        |       ^~~~~~~~
  /tmp/0RmVdQYjfA.cpp:37:7: note:   candidate expects 0 arguments, 1 provided
  /tmp/0RmVdQYjfA.cpp:37:7: note: candidate: 'constexpr concrete::concrete(const concrete&)'
  /tmp/0RmVdQYjfA.cpp:37:7: note:   no known conversion for argument 1 from 'const clone_inherit<concrete, cloneable>' to 'const concrete&'
  /tmp/0RmVdQYjfA.cpp:37:7: note: candidate: 'constexpr concrete::concrete(concrete&&)'
  /tmp/0RmVdQYjfA.cpp:37:7: note:   no known conversion for argument 1 from 'const clone_inherit<concrete, cloneable>' to 'concrete&&'

要修复第 32 行中的这个错误,我必须准确返回指向派生类的返回指针,如下所示:

  //   return  new static_cast<Derived*>(*this); to replace with 
  return new Derived(static_cast<const Derived&>(*this));

有人可以建议解决这个问题的正确方法吗?

c++ inheritance constructor c++17 smart-pointers
1个回答
0
投票

您可以添加隐式转换:

template <typename Derived, typename Base>
class clone_inherit : public Base {
 public:
  std::unique_ptr<Derived> clone() const {
    return std::unique_ptr<Derived>(static_cast<Derived *>(this->clone_impl()));
  }

 private:
  // added
  operator const Derived &() const {
    return static_cast<const Derived &>(*this);
  }

  virtual clone_inherit *clone_impl() const override {
    return new Derived(*this);  // getting error here
  }
};

© www.soinside.com 2019 - 2024. All rights reserved.