Ant*_*ois 17 c++ polymorphism c++11
考虑以下类
class Base {
public:
virtual void do_stuff() = 0;
};
class Derived : public Base {
public
virtual void do_stuff() { std::cout << "I'm useful"; };
};
Run Code Online (Sandbox Code Playgroud)
现在让我们说我想让另一个类负责拥有Base派生类型的对象,并通过它们调用它们的do_stuff()方法进行迭代.它看起来像这样,但我不知道T应该声明什么
class Owner {
public:
void do_all_stuff() {
//iterate through all items and call do_stuff() on them
}
void add_item(T item) {
items.push_back(item);
}
vector<T> items;
}
Run Code Online (Sandbox Code Playgroud)
我看到了一些可能性:
T不可能Base,因为我只能添加具体类型的对象Base,所以这是不可能的.
T可以是Base*或Base&,但现在我需要信任调用者add_item()传递一个指针或对一个对象的引用,当我从中检索它时它仍然存在items.我不能解析析构函数中delete的元素Owner,因为我不知道它们是动态分配的.但是,他们应该是delete'如果他们是,这让我拥有模糊的所有权.
T可以Base*或者Base&我添加一个Base* create_item<DerivedT>() { return new DerivedT; }方法Owner.这样,我知道指针将保持有效并且我拥有它,但是我无法调用非默认构造函数DerivedT.此外,还Owner负责实例化对象.我还必须删除Owner析构函数中的每个项目,尽管这不是问题.
基本上,我希望能够做类似的事情:
Owner owner;
void add_one() {
Derived d;
owner.add_item(d);
}
void ready() {
owner.do_all_stuff();
}
void main() {
for(int i = 0; i < 10; ++i) {
add_one();
}
ready();
}
Run Code Online (Sandbox Code Playgroud)
我确信在那里有一些与移动语义相关的东西(我可以移动传递给add_items()它们的对象)但是我仍然无法弄清楚我的集合是如何被声明的.
这种多态所有权的C++习语是什么(特别是对于STL容器)?
bam*_*s53 19
多态对象必须由指针或引用处理.由于它们的生命周期可能不受特定范围的约束,因此它们也可能具有动态存储持续时间,这意味着您应该使用智能指针.
智能指针如std::shared_ptr和std::unique_ptr工作只是在标准集合类型的罚款.
std::vector<std::unique_ptr<Base>>
Run Code Online (Sandbox Code Playgroud)
使用它Owner看起来像:
class Owner {
public:
void do_all_stuff() {
//iterate through all items and call do_stuff() on them
}
void add_item(std::unique_ptr<Base> item) {
items.push_back(std::move(item));
}
vector<std::unique_ptr<Base>> items;
}
Run Code Online (Sandbox Code Playgroud)
参数类型用于add_item标识添加项目所需的所有权策略,并要求用户尽力将其搞砸.例如,它们不会意外地使用一些隐含的,不兼容的所有权语义传递原始指针,因为unique_ptr它具有显式构造函数.
unique_ptr还将负责删除所拥有的对象Owner.虽然您确实需要确保Base具有虚拟析构函数.根据您当前的定义,您将获得未定义的行为.多态对象应该总是有一个虚拟析构函数.
| 归档时间: |
|
| 查看次数: |
2239 次 |
| 最近记录: |