【问题标题】:Polymorphism with smart pointer带智能指针的多态性
【发布时间】:2020-10-08 22:51:19
【问题描述】:

正如答案所指出的,这是我犯的一个愚蠢的错误,与多态性或智能指针无关。更正的版本在接受的答案中。

============== 原问题 ==================

我正在尝试使智能指针与多态一起工作。在下面的原型代码中,纯virtual函数Base::print()的实现应该在Derived对象的内存块中。 DerivedWrap 可以访问指向 Derived 对象的指针。

为什么DerivedWrap::print()不能访问函数实现?

using namespace std;

class Base 
{
public:
    virtual void print() = 0;
};

class Derived : public Base 
{
public:
    Derived(int in) : i(in) {}

    void print() {
        cout << "int is " << i << endl;
    }

private:
    int i;
};

class DerivedWrap 
{
public:
    DerivedWrap() : DerivedWrap(make_unique<Derived>(2)) {}
    DerivedWrap(unique_ptr<Base> pBase) : _pBase(move(pBase)) {}

    void print()
    {
        _pBase->print();
    }

private:
    unique_ptr<Base> _pBase;
};

int main() 
{
    DerivedWrap pDW1();
    pDW1->print(); // error: request for member ‘print’ in ‘pDW1’, which is of non-class type ‘DerivedWrap()’

    DerivedWrap pDW2(make_unique<Derived>(2));
    pDW2->print(); // error: base operand of ‘->’ has non-pointer type ‘DerivedWrap’
    return 0;
}

【问题讨论】:

    标签: c++ class c++11 polymorphism smart-pointers


    【解决方案1】:

    你有一些错别字,应该是:

    int main()
    {
      DerivedWrap pDW1; // object instantiation, no () needed
      pDW1.print(); //no dereferencing required
    
      DerivedWrap pDW2(make_unique<Derived>(2));
      pDW2.print(); // again, no dereference required
    
      return 0;
    }
    

    另外一点,对于多态对象,您需要在基类中使用虚拟析构函数。

    【讨论】:

      【解决方案2】:

      你有几个问题。

      • 这个DerivedWrap pDW1();是一个函数声明,它的返回 类型是DerivedWrap。它没有调用您期望的默认构造函数。你只需要
        DerivedWrap pDW1;  // calls the default constructor
        // or 
        // DerivedWrap pDW1{};
        
      • 其次,pDW1 只是一个 DerivedWrap 对象。因此,无需致电operator-&gt;。 简而言之,您需要
        DerivedWrap pDW1;
        pDW1.print(); 
        
        这同样适用于pDW2。你需要
        DerivedWrap pDW2(std::make_unique<Derived>(2));
        pDW2.print();
        
      • 最后但并非最不重要的一点是,Base 必须具有用于定义行为的 virtual 析构函数。查看更多: When to use virtual destructors?

      总之,你需要

      #include <iostream>
      #include <memory>
      
      class Base
      {
      public:
         virtual void print() = 0;
         virtual ~Base() = default;  // provide virtual destructor
      };
      
      class Derived /*final*/: public Base
      {
      public:
         // ... other code
      
         void print() override // recommended to override the virtual functions
         {
            std::cout << "int is " << i << std::endl;
         }
      private:
         int i;
      };
      
      class DerivedWrap /* final */
      {
      public:
         // ...other code
      
         void print()
         {
            _pBase->print();
         }
      
      private:
         std::unique_ptr<Base> _pBase;
      };
      
      int main()
      {
         DerivedWrap pDW1; // or DerivedWrap pDW1{};
         pDW1.print();
      
         DerivedWrap pDW2{ std::make_unique<Derived>(2) };
         pDW2.print();
      }
      

      作为旁注,请do not practice with using namespace std;

      【讨论】:

        【解决方案3】:

        这与多态性、虚函数或智能指针无关。

        你只是犯了两个小印刷错误:

        1. DerivedWrap pDW1(); 声明了一个函数。删除()
        2. -&gt; 取消引用指针,但 pDW1pDW2 都不是函数。请改用.

        【讨论】:

          猜你喜欢
          • 2013-05-10
          • 2013-05-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-07-03
          相关资源
          最近更新 更多