我想持有一个基类实例的向量,无需对象切片(这样我也可以存储Base的子实例而没有问题),同时保持多态行为而不通过复制值添加到列表中,而是通过引用。这是在现代C++糟糕做法中使用原始指针吗?
考虑以下源文件:
#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;
}
我得到以下输出:
ent = player, edited = 1.
作为输出显示(通过打印出“运动员”和表示“编辑”的变化) ,由于原始指针而保持多态行为,并且我能够编辑列表的成员而没有问题。
为了澄清我所问:我可以改为使用std :: reference_wrapper来实现完全相同的行为吗?当我尝试使用reference_wrapper时,无法实现相同的行为,因为需要指针才能实现这种多态行为?如果reference_wrappers不是一个可行的选择,尽管我完全知道我添加到向量中的Player实例是一个堆栈变量,但是使用shared_ptr代替它会是明智的吗?在我特别的例子中,我赞成shared_ptr,因为我希望共享向量成员的所有权。有没有更好的方法来实现这种行为?
我不会说原始指针的* use *必然是坏的。我会说原始指针的显式管理*(即分配,删除)是不被接受的。只是指向一个对象,但不会声称拥有这个内存,不是太糟糕,但是经常有更好的选择。 – CoryKramer
C++中的“不良实践”不仅仅是一种语言,它还与你正在做的事情有关。例如,如果您正在开发一个小型,高效的库,您的准则可能会说使用原始指针来避免两个间接层。如果您正在制作游戏,那么您不需要担心始终分配对象的(分配),因此使用智能指针将是一个很好的实践。我甚至会说在那种情况下,非拥有的raw指针应该被weak_ptr所取代。 – ZeroUltimax
有[std :: observer_ptr](http://en.cppreference.com/w/cpp/experimental/observer_ptr)明确指出你的指针没有拥有。 – Jarod42