c++ - 带智能指针的多态性

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

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

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

我正在尝试使智能指针与多态性一起使用。在下面的原型(prototype)代码中,纯 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;
}

最佳答案

你有几个问题。

  • 这个DerivedWrap pDW1();是一个函数声明,其返回
    类型是 DerivedWrap .它没有调用您期望的默认构造函数。你只需要
    DerivedWrap pDW1;  // calls the default constructor
    // or 
    // DerivedWrap pDW1{};
    
  • 其次,pDW1只是一个 DerivedWrap目的。因此,无需调用operator-> .
    简而言之,您需要
    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;

    关于c++ - 带智能指针的多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62457465/

    相关文章:

    接口(interface)或类中的 PHP 类构造函数

    javascript - 如何创建函数模型?

    c++ - 是否可以在已分配的内存上初始化 std::vector ?

    c++ - ISO 文档 : based on Anonymous Unions 中的一点

    c++ - 存档没有索引;运行 ranlib 以在 Dev C++ 中添加一个

    没有循环包含的C++调用成员函数

    java - 如何编写不同典型 Java 类的实例?

    c++ - 如何与命名构造函数一起处理不可复制成员?

    c++ - Mac OS X 中 undefined reference _cblas_dgemm

    c++ - 'Button_Click' : is not a member of 'ButtonTest::MainPage'