代码之家  ›  专栏  ›  技术社区  ›  GPrathap

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

  •  1
  • GPrathap  · 技术社区  · 6 月前

    我在跟踪 this tutorial 了解如何在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行错误 ,我必须精确地返回一个Derived类的返回指针,如下所示:

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

    有人能提出解决这个问题的正确方法吗?

    1 回复  |  直到 6 月前
        1
  •  1
  •   3CxEZiVlQ    6 月前

    您可以添加私有隐式或显式强制转换运算符:

    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 here
      explicit operator const Derived &() const {
        return static_cast<const Derived &>(*this);
      }
    
      virtual clone_inherit *clone_impl() const override {
        return new Derived(*this);  // not getting error here
      }
    };