C ++析构函数与载体,指针(C++ Destructors with Vectors, Point

2019-06-27 05:54发布

据我知道,我要摧毁我创建析构函数的一切new和关闭打开文件流和其他流。 不过,我对C ++中的其他对象有些疑惑:

  • std::vectorstd::string S:他们是否自动销毁?

  • 如果我有这样的事情

     std::vector<myClass*> 

    的指针类。 会发生什么事矢量调用析构函数?
    难道自动调用析构函数myClass ? 或仅载体被破坏,但所有的对象包含在内存中仍然existant?

  • 如果我有一个指向类中其他类情况,说:

     class A { ClassB* B; } 

    和A类是在代码中的一些点被破坏。 将B级太破坏或只是指针和B类将仍然存在于记忆的地方?

Answer 1:

的std :: vector和std ::字符串:他们自动销毁?

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

如果我有类似的std ::向量时会发生什么矢量调用析构函数? 难道自动调用MyClass的析构函数? 或仅载体被破坏,但所有的对象包含在内存中仍然existant?

如果vector<MyClass>然后包含于载体中的所有对象将被破坏。 如果vector<MyClass*>那么所有的对象必须是明确地delete d(假定被破坏的类拥有该对象vector )。 第三种选择是vector智能指针,如vector<shared_ptr<MyClass>> ,在这种情况下的元素vector不需要显式地delete d。

如果我有一个指针恰好另一个类是什么类的内部

B必须明确delete d。 再次,一个智能指针可用于处理的破坏B



Answer 2:

你只需要担心你已经创建动态内存(当你保留内存与new 。)

例如:

Class Myclass{
   private:
       char* ptr;
   public:
       ~Myclass() {delete[] ptr;};
}


Answer 3:

  • 如果他们在自动存储,是的。 你可以拥有std::string* s = new std::string ,在这种情况下,你必须自己删除。

  • 什么,你需要手动删除您自己的内存(用于分配的内存new )。

  • 如果您分配bnew ,你应该在析构函数销毁它明确。

一个好的经验法则是使用delete/delete[]为每个new/new[]你必须在你的代码。

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



Answer 4:

这取决于。 std::vectorstd::stringMyClass都有1个共同点-如果声明一个变量是任何这些类型的,那么它会在堆栈中分配,是本地的当前块你在和当该块结束遭到破坏。

{
    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个字节的整数)将在离开范围自动释放内存。 没有任何反应的指向的内存,除非你明确地delete它(不管它是在载体或者不是)。 如果您有包含指向您可能必须删除他们在析构函数(取决于类是否拥有这些对象)其他对象的类。 请注意,在C ++ 11有指针类(被称为智能指针),让您以类似的方式“正常”的对象对待指针:

例如:

{
    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


Answer 5:

如果我有类似的std ::向量时会发生什么矢量调用析构函数?

这取决于。

如果你有的向量std::vector <MyClass> ,那么向量的析构函数要求对每个实例的析构函数MyClass向量中。

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

如果我有一个指针恰好另一个类是什么类的内部

ClassB实例将保留在内存中。 可能的方法有ClassA析构函数,使工作为你做出B实例成员或智能指针。



Answer 6:

std::vectorstd::string而据我所知其他所有STL容器具有自动析构函数。 这就是为什么它往往是更好地使用这些容器,而不是原因, newdelete ,因为你将防止内存泄漏。

myClass ,如果你的载体是一个矢量析构函数才会被调用myClass对象( std::vector< myClass > ),而不是一个指针的向量myClass对象( std::vector< myClass* >

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

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



Answer 7:

  1. 是。 std::vectorstd::string当他们完成超出范围,也包含调用对象的析构函数(为是自动std::vector )。

  2. 正如前面所说的, std::vector当它完成超出范围被破坏,调用对象的析构函数包含。 但事实上,在这种情况下,包含的对象是指针,而不是由指针指向的对象。 所以,你必须delete手动它们。

  3. 相同(2)。 A将被破坏,使指针,而不是B级指出。 你必须提供对一个析构函数delete B.

在C ++ 11有一个非常有用的解决方案:使用std::unique_pointer 。 只能使用指向一个对象,当指针超出范围(例如,当你摧毁你的,这将被删除std::vector )。

http://en.cppreference.com/w/cpp/memory/unique_ptr



Answer 8:

据我所知,这应该工作如下:

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

这是你想要的吗?



文章来源: C++ Destructors with Vectors, Pointers,