简体   繁体   English

如何防止超出范围复制的对象调用析构函数

[英]How to prevent out of scope copied object from calling the destructor

So I have this code down there which is a dummy version of my main code and is supposed to create an object stored in a vector.所以我有这段代码,它是我的主代码的虚拟版本,应该创建一个存储在向量中的对象。 Since the object goes out of scope when the creator function ( spawns() ) ends, calling it's destructor and freeing picture I needed to create instead a shared_ptr inside spawn .由于对象在创建者函数( spawns() )结束时超出范围,因此调用它的析构函数并释放picture我需要在spawn内部创建一个 shared_ptr 。 And make the vector Entities a vector of shared pointers which goes out of scope only when there aren't any pointers to it anymore.并使向量实体成为共享指针的向量,仅当不再有任何指向它的指针时才超出范围。 Keeping my precious picture.保留我珍贵的照片。

Until here no problems.直到这里没有问题。 But the teacher asked us to add a save button to our game which records all the objects to a json file using nlohmann's code which makes necessary to store actual values inside the vector Entities ,not pointers which would be useless used in another instance of the program.但是老师要求我们在我们的游戏中添加一个保存按钮,该按钮使用nlohmann 的代码将所有对象记录到一个 json 文件中,这使得必须在向量Entities存储实际值,而不是在程序的另一个实例中无用的指针. So I need to know if there is any way to instead of copying a value with push_back to a vector, generate the object already inside it somehow.所以我需要知道是否有任何方法可以代替将带有 push_back 的值复制到向量,而是以某种方式生成已经在其中的对象。 Or somehow using pointers inside nlohmann's json parser.或者以某种方式在 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;
}

I found a much easier solution that is just initializing my objects after they are already in the vector.我找到了一个更简单的解决方案,它只是在我的对象已经在向量中之后初始化它们。 But I also learned how to do it the hard way for the sake of learning c++.但为了学习 C++,我也学会了如何以艰难的方式去做。 Basically there are move constructors which are called when you use std::move(a) as suggested by KamilCuk where a is the object which moves the content of 'a' instead of copying it.基本上,当您按照 KamilCuk 的建议使用 std::move(a) 时会调用移动构造函数,其中 a 是移动 'a' 内容而不是复制它的对象。 Though it 'a' has a declared destructor c++ will still call it on the remains of the object variable from which it was moved when it's out of scope.尽管它 'a' 有一个声明的析构函数,但当它超出范围时,c++ 仍然会在它被移动的对象变量的剩余部分上调用它。 Making it useless for my situation.让它对我的情况毫无用处。

So here comes in the ' move constructor ' which runs when you move your object.所以这里出现了“ 移动构造函数”,它在您移动对象时运行。 And where you can change your pointer to nullptr so that nothing happens when the destructor runs and frees it.您可以在哪里更改指向 nullptr 的指针,以便在析构函数运行并释放它时不会发生任何事情。 And in your vector the pointer is available for you.在您的向量中,指针可供您使用。 Down there is my code:下面是我的代码:

#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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当对象超出范围时是否调用析构函数? - Is a destructor called when an object goes out of scope? 对象超出范围之前调用的析构函数 - Destructor Called Before Object Goes Out Of Scope 如何防止临时范围超出范围? - How to prevent a temporary from going out of scope? 为什么当对象超出范围时我们说析构函数调用? - Why We Say Destructor Call When Object Goes out of Scope? 当这些对象中的任何一个没有超出范围时,为什么要调用析构函数? - Why destructor is called when any of these object not going out of scope? 强制对象解除分配/超出范围以调用析构函数 - Forcing object to deallocate/go out of scope to call destructor exit()或异常会阻止调用范围的析构函数吗? - Will exit() or an exception prevent an end-of-scope destructor from being called? 如果一个Object从堆中分配动态内存,它是否在对象超出范围时自动解除分配,还是需要析构函数? - If an Object allocates dynamic memory from the heap, is it automatically de-allocated when the object is out of scope or do I need a destructor? 在C ++中,如果我引用带有析构函数的析构函数〜MyClass的对象,则超出范围的引用会调用析构函数吗? - In C++ if I reference an object with a deallocating destructor ~MyClass, will the reference going out of scope invoke the destructor? 在C ++中调用delete时是否可以防止析构函数运行? - Is it possible to prevent the destructor from running when calling delete in C++?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM