带向量,指针的C ++析构函数,

C++ Destructors with Vectors, Pointers,

据我所知,我应该在析构函数中销毁我用new创建的所有内容,并关闭打开的文件流和其他流。但是,我对C++中的其他对象有一些疑虑:

  • std::vectorstd::strings:它们是自动销毁的吗?

  • 如果我有类似的东西

    1
    std::vector<myClass*>

    指向类的指针。调用向量析构函数时会发生什么?它会自动调用myClass的析构函数吗?或者只有向量被销毁,但它所包含的所有对象仍然存在于内存中?

  • 如果我在一个类中有一个指向另一个类的指针,会发生什么情况,比如:

    1
    2
    3
    class A {
      ClassB* B;
    }

    A类在代码中的某一点被销毁。类B也将被销毁,或者只是指针和类B仍将存在于内存中的某个地方?


std::vector and std::strings: Are they destroyed automatically?

是(假设成员变量不是指向std::vectorstd::string的指针)。

If I have something like std::vector what happens when the vector destructor is called?
Would it call automatically the destructor of myClass? Or only the vector is destroyed but all the Objects it contains are still existant in the memory?

如果vector,那么向量中包含的所有对象都将被销毁。如果vector那么所有对象都必须显式地为deleted(假设被销毁的类拥有vector中的对象)。第三种选择是智能指针的vector,如vector>,在这种情况下,vector的元素不需要明确地表示为deleted。

What happens if I have a pointer to another class inside a class

B必须是明确的deleted。同样,可以使用智能指针来处理B的销毁。


您只需要担心动态创建的内存(当您使用new保留内存时)。

例如:

1
2
3
4
5
6
Class Myclass{
   private:
       char* ptr;
   public:
       ~Myclass() {delete[] ptr;};
}


这要看情况而定。std::vectorstd::stringMyClass都有一个共同点——如果您声明一个变量是这些类型中的任何一种,那么它将在堆栈上分配,在您所在的当前块上是本地的,并在该块结束时被销毁。

例如。

1
2
3
4
5
{
    std::vector<std::string> a;
    std::string b;
    MyClass c;
} //at this point, first c will be destroyed, then b, then all strings in a, then a.

如果您到达指针,您会正确猜测:只有指针本身所占用的内存(通常是4字节整数)在离开作用域时才会自动释放。除非您显式地使用cx1(4),否则所指向的内存不会发生任何变化(无论它是否在向量中)。如果有一个类包含指向其他对象的指针,则可能需要在析构函数中删除它们(取决于该类是否拥有这些对象)。请注意,在C++ 11中有指针类(称为智能指针),它们可以以类似的方式处理指针到"正常"对象:

前任:

1
2
3
4
{
    std::unique_ptr<std::string> a = make_unique<std::string>("Hello World");
    function_that_wants_string_ptr(a.get());
} //here a will call delete on it's internal string ptr and then be destroyed


  • 如果它们在自动存储中,是的。您可以使用std::string* s = new std::string,在这种情况下,您必须自己删除它。

  • 不需要,您需要手动删除您拥有的内存(对于与new一起分配的内存)。

  • 如果您将B分配给new,您应该在析构函数中明确地销毁它。

一个好的经验法则是对代码中的每个new/new[]使用delete/delete[]

更好的经验法则是使用RAII,使用智能指针而不是原始指针。


  • 是的。当他们std::stringare std::vector和自动完成的范围,对象的析构函数调用的,也包含(std::vector)。

  • std::vectoris M的说,当它完成的范围内,调用析构函数的对象的存在。但事实上,在这个案例中,该对象的存在,是不分对象,分尖的。你必须手动delete他们。

  • (2)相同的。这将是在M和B类的指针,而不是尖的。你提供的是一delete析构函数。

  • 在C + +的解决方案有一个11 std::unique_pointer非常有用的使用。可以仅仅使用单点的对象,这将被删除当指针超出范围(例如当你消灭你的std::vector)。

    en.cppreference.com http:/ / / / / / w的)独特的_ CPP存储器


    据我所知,所有其他STL容器都有自动销毁器。这就是为什么使用这些容器而不是newdelete更好的原因,因为这样可以防止内存泄漏。

    只有当向量是MyClass对象(std::vector< myClass >的向量,而不是指向MyClass对象(std::vector< myClass* >的指针向量)时,才会调用MyClass析构函数。

    在第一种情况下,std::vector的析构函数也会为其每个元素调用MyClass的析构函数;在第二种情况下,std::vector的析构函数会调用myClass*的析构函数,这意味着它将释放用于存储每个指针的空间,但不会释放用于存储MyClass对象的空间。TS本身。

    您指向的Class B对象不会被销毁,但分配给存储其指针的空间将被释放。


    If I have something like std::vector what happens when the vector destructor is called?

    这要看情况而定。

    如果有一个值为std::vector 的向量,那么该向量的析构函数调用该向量中MyClass的每个实例的析构函数。

    如果你有一个指针向量std::vector ,那么你负责删除MyClass的实例。

    What happens if I have a pointer to another class inside a class

    ClassB实例将保留在内存中。使ClassA析构函数为您生成作业的可能方法是使B成为实例成员或智能指针。


    我的理解是,这工作应该如下:

    1
    2
    3
    4
    5
    vector <int> test_vector = {1,2,3,4,5,6,7} // Call vector constructor

    ... Any manipulations with a vector ...

    test_vector.~vector(); // Call vector destructor

    那是你想要的吗?