Har*_*and 6 c++ polymorphism smart-pointers stdvector c++11
我想要保存一个没有对象切片的Base类实例的向量(这样我也可以存储没有问题的Base的子实例),同时保持多态行为,而不是通过复制值而是通过引用添加到列表中.
请考虑以下源文件:
#include <iostream>
#include <string>
#include <vector>
#include <memory>
class Entity
{
public:
Entity(){this->edited = false;}
virtual std::string name() = 0;
bool edited;
};
class Player: public Entity
{
public:
Player(): Entity(){}
std::string name(){return "player";}
};
int main()
{
std::vector<Entity*> entities;
Player p;
entities.push_back(&p);
entities.at(0)->edited = true;
Entity* ent = entities.at(0);
std::cout << "ent = " << ent->name() << ", edited = " << ent->edited << ".\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我获得以下输出:
ent = player, edited = 1.
Run Code Online (Sandbox Code Playgroud)
当输出显示(通过打印出"播放器"并显示"已编辑"中的更改)时,由于原始指针而保持多态行为,并且我能够毫无问题地编辑列表成员.
澄清我在问什么:我可以使用std :: reference_wrapper来实现完全相同的行为吗?当我尝试使用reference_wrapper时,由于需要指针来实现这种多态行为,所以无法实现相同的行为?如果reference_wrappers不是一个可行的选择,虽然我完全知道我添加到向量中的Player实例是一个堆栈变量,但是使用shared_ptr是否明智?在我的特定示例中,我倾向于使用shared_ptr,因为我想要向量的成员共享所有权.有没有更好的方法来实现这种行为?
在现代c ++中,非拥有指针很好.但是如果你的指针是拥有的,你最好有一个很好的理由使用原始指针而不是智能指针.即使在最坏的情况下,您仍然可以编写自己的智能指针.您的示例是非拥有指针.
使用std::reference_wrapper<T>在这里没有任何收获.我已经包含了你的例子,修改后使用它.请注意,直接操作向量中的元素会稍微烦一些.
int main()
{
std::vector<std::reference_wrapper<Entity>> entities;
Player p;
entities.push_back(p);
entities.front().get().edited = true;
Entity & ent = entities.front();
std::cout << "ent = " << ent.name() << ", edited = " << ent.edited << ".\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
原始指针只是一种工具,就像c ++提供的许多其他工具一样.当它是正确的工具时,不要害怕使用它.现代c ++带来的最重大变化是它已经取消了拥有原始指针.经验法则是你必须记住delete你做错了.
请注意,这std::vector<T>::front()是获取第一个元素的首选方法,std::vector::at当您知道索引有效时,不鼓励使用.
| 归档时间: |
|
| 查看次数: |
1552 次 |
| 最近记录: |