所以我有这个代码,它是我主代码的伪版本,应该创建一个存储在向量中的对象。由于当创建者函数(spawns()
(结束时,对象超出了范围,因此调用它的析构函数并释放picture
,我需要在spawn
内创建一个shared_ptr。并使向量实体成为共享指针的向量,只有当不再有指向它的指针时,它才会超出范围。保留我珍贵的照片。
直到这里没有问题。但老师要求我们在游戏中添加一个保存按钮,该按钮使用nlohmann的代码将所有对象记录到json文件中,这使得有必要将实际值存储在向量Entities
中,而不是在程序的另一个实例中使用的无用指针。因此,我需要知道是否有任何方法可以代替将带有push_back的值复制到向量,而是以某种方式生成已经在其中的对象。或者以某种方式在nlohmann的json解析器中使用指针。
#include <iostream>
#include <memory>
#include <vector>
class entity{
public:
~entity();
int batata=12;
Texture * picture;
};
entity::~entity(){
delete picture;
std::cout<<"destroyed"<<std::endl;
}
void spawns(std::vector <shared_ptr<entity>> &Entities){
std::shared_ptr <entity> ent (new entity);
Entities.push_back(ent);
}
int main(){
std::vector <shared_ptr<entity>> Entities;
spawns(Entities);
std::cout<<Entities[0]->batata<<std::endl;
return 0;
}
我发现了一个更简单的解决方案,只需在对象已经在向量中之后初始化它们。但为了学习c++,我也学会了如何用艰苦的方式来完成它。基本上,当你使用KamilCuk建议的std::move(a(时,会调用一些move构造函数,其中a是移动"a"内容而不是复制它的对象。尽管它"a"有一个声明的析构函数,但当它超出范围时,c++仍会在移动它的对象变量的剩余部分调用它。让它对我的处境毫无用处。
所以这里有一个"移动构造函数",当你移动对象时它会运行。在这里,你可以将指针更改为nullptr,这样当析构函数运行并释放它时就不会发生任何事情。在你的向量中,指针对你来说是可用的。下面是我的代码:
#include <iostream>
#include <utility>
#include <memory>
#include <vector>
class entity{
public:
int batata=12;
std::string * picture;
entity() { }
~entity();
entity(entity&& o) noexcept : //this is the move constructor
picture(std::move(o.picture)) // explicit move of a member of class type
{
o.picture=nullptr;
}
};
entity::~entity(){//destructor
std::cout<<"destroyed"<<std::endl;
delete picture;//frees the pointer
}
void spawns(std::vector <entity> &Entities){//initializes
std::string* str=(new std::string);
(*str)="batata";
entity ent;
ent.picture=str;
Entities.push_back(std::move(ent));
}
int main(){
std::vector <entity> Entities;
spawns(Entities);
std::cout<<*(Entities[0].picture)<<std::endl;
return 0;
}