我创建了一个抽象类,然后创建了继承此抽象类的子类。
class A{
public:
virtual A* clone() const = 0;
virtual A* create() const = 0;
~virtual A(){};
// etc.
};
子课程
class B: public A{};
class C: public A{};
然后,我使用子类指针隐式转换为main函数中的基类指针。
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还是将类对象销毁 - 这是我的初衷。需要一些清晰度。
答案 0 :(得分:1)
为什么不尝试这样做?
下面的示例提供了一种方法,您可以在其中创建Foo
(您的抽象基类)和两个实现该接口的派生类(在本例中为Bar
和std::unique_ptr<Interface>
)。
然后,您可以创建一个emplace_back
容器(指向抽象基类的唯一指针),并使用各种方法和辅助函数填充它:std::make_unique
push_back
,{{1} } std::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