【问题标题】:unique_ptrs and converted pointers and a vectorunique_ptrs 和转换后的指针和一个向量
【发布时间】:2015-10-07 10:49:18
【问题描述】:

我创建了一个抽象类,然后创建了继承这个抽象类的子类。

  class A{
       public:
       virtual A* clone() const = 0;
       virtual A* create() const = 0;
       ~virtual A(){};
       // etc.

  };

子类

     class B: public A{};
     class C: public A{};

然后我在主函数中使用子类指针到基类指针的隐式转换。

     int main(){

     B* pB = new B();
     C* pC = new C();

     A* pA = pB;     //converting a pointer to A, to a pointer to B
     A* pAA = pC;    //converting a pointer to A, to a pointer to C

我现在可以使用 A 类型的指针用这些类填充向量,并通过多态性访问子类。

    vector<A*> Pntr;

但是,我希望每个子类负责自己的内存释放。我知道我可以为此使用唯一指针。问题是我该如何实现。

如果我这样编码:

    pA = unique_ptr<A>(pB);
    pAA = unique_ptr<A>(pC);

然后我像这样填充向量:

    vector<unique_ptr<A>>Pointers;
    Pointers.push_back(move(pA));
    Pointers.push_back(move(pAA));

不确定这是否可行。而且我也很困惑,当向量超出范围时实际上会被销毁。转换后的指针 pA 和 pAA 会被简单地设置为 NULL 还是类对象会被销毁——这是我的初衷。需要一些澄清。

【问题讨论】:

  • 我觉得没问题。为什么不尝试一下
  • 就像我answered你之前的问题一样,类对象将被销毁。但是,您不能将 unique_ptr 分配给原始指针,这就是您正在做的事情。
  • 感谢您对这个问题和我之前的问题的所有回复。我现在正在尝试,除了我必须像这样使用 auto : auto pA = unique_ptr(pB);

标签: c++ c++11 vector unique-ptr


【解决方案1】:

你为什么不试试呢?

下面的示例提供了一种方法,您可以在其中创建一个Interface(您的抽象基类)和两个实现该接口的派生类(在本例中为FooBar)。

然后您可以创建一个包含std::unique_ptr&lt;Interface&gt;(指向抽象基类的唯一指针)的容器,并使用各种方法和辅助函数填充它:emplace_backstd::make_uniquepush_backstd::move,等等开。

运行示例后,您会注意到析构函数被自动调用 --- 这就是 std::unique_ptr 的美妙之处。

#include <cassert>
#include <memory>
#include <vector>
#include <iostream>

class Interface {
 public:
  virtual ~Interface() {
    std::cout << "Destroying object" << std::endl;
  }
  virtual void Method() const = 0;
};

class Foo // Foo "implements" or "offers access to" the Interface
    : public Interface {
 public:
  void Method() const override { // here we override Interface::Method
    std::cout << "Foo::Method" << std::endl;
  }
};

class Bar // Bar "implements" or "offers access to" the Interface
    : public Interface {
 public:
  void Method() const override { // here we override Interface::Method
    std::cout << "Bar::Method" << std::endl;
  }
};


int main() {
  // declare
  std::vector<std::unique_ptr<Interface>> objects;

  // populate
  objects.emplace_back(std::make_unique<Foo>());
  objects.emplace_back(std::make_unique<Bar>());
  objects.emplace_back(std::make_unique<Foo>());

  // another way to populate
  std::unique_ptr<Foo> pfoo(new Foo);
  objects.push_back(std::move(pfoo));

  // but be careful... pfoo now points to nullptr because you
  // moved ("transfered control of") the pointer to the
  // vector; pfoo no longer owns it (so it owns nothing; it is a
  // nullptr)
  assert(pfoo == nullptr);

  // you can iterate over all members by REFERENCE (otherwise you
  // would need to make copies, and you cannot copy a unique_ptr)
  for(const auto & pobject : objects) {
    pobject->Method();
  }

  // at exit you should see the calls to the destructor

  return 0;

}

编译运行:

$ g++ example.com -std=c++14 -Wall -Wextra
$ ./a.out
Foo::Method
Bar::Method
Foo::Method
Foo::Method
Destroying object
Destroying object
Destroying object
Destroying object

【讨论】:

    猜你喜欢
    • 2021-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-04
    • 2020-10-23
    相关资源
    最近更新 更多