C++ 如何取消分配向量中的对象指针?

C++ 如何取消分配向量中的对象指针?,c++,vector,C++,Vector,我有 class object { // any private datas token in heap area public : ~object () ; }; 在功能上 vector < object*> tmp ; vectortmp; 我的问题是, 如何擦除/解除分配tmp[I]?换句话说,我应该在object::destructor中写些什么 析构函数

我有

class object {
                    // any private datas token in heap area 
             public : 
                   ~object () ; 

};
在功能上

 vector < object*> tmp ;
vectortmp;
我的问题是,

  • 如何擦除/解除分配tmp[I]?换句话说,我应该在object::destructor中写些什么
析构函数应包含释放内存对象所占用的所有必要内容

由于该对象指针存储在向量中,所以在销毁它之后应该删除对它的引用。也就是说,从向量中删除该对象*。

您可以使用


您的
对象
析构函数应该
删除您在堆中分配的所有成员。

您似乎有点困惑。这里有两个概念:

  • 作为
    tmp
    的所有者,我如何解除分配
    tmp
    中指针引用的对象
  • 对象
    类(
    ~对象
    )的析构函数应该做什么
这些其实并不是那么相关。完成
tmp
向量后,必须手动遍历并调用其每个元素上的
delete
,以释放元素指向的
对象所占用的内存。当然,这是假设元素被分配了
new

对象
析构函数
~对象
的目的是解除分配
对象
对象所拥有的一切,而不是解除分配
对象
对象本身。如果
对象
对象不拥有任何动态分配的数据,则不需要执行任何操作

换句话说,当您编写
删除tmp[i]
时,会发生两件事:

  • 调用
    *(tmp[i]):~object()
  • tmp[i]
    指向的内存被释放
  • 注意,(2)即使(1)什么都不做也会发生。步骤(1)的要点是允许即将解除分配的对象解除分配其需要解除分配的任何成员对象。析构函数的任务显然不是取消分配调用它的对象

    通过明确的例子:

    class object {
      private:
        int foo;
      public:
        object() : foo(42) {}
        ~object() { /* nothing to do here; foo is not dynamically allocated */ }
    };
    
    int main() {
      vector<object*> tmp;
      tmp.push_back(new object());
    
      // Do some stuff with tmp
    
      for (int i = 0; i < tmp.size(); ++i) {
        delete tmp[i]; // Calls ~object and deallocates *tmp[i]
      }
      tmp.clear();
    
      return 0;
    }
    
    类对象{
    私人:
    int foo;
    公众:
    object():foo(42){}
    ~object(){/*此处无需操作;未动态分配foo*/}
    };
    int main(){
    向量tmp;
    tmp.push_back(新对象());
    //用tmp做一些事情
    对于(int i=0;i
    或者,相比之下

    class object {
      private:
        int* foo;
      public:
        object() : foo(new int()) { *foo = 42; }
        ~object() { 
          // Now since foo is dynamically allocated, the destructor
          // needs to deallocate it
          delete foo;
        }
    };
    
    int main() {
      vector<object*> tmp;
      tmp.push_back(new object());
    
      // Do some stuff with tmp
    
      for (int i = 0; i < tmp.size(); ++i) {
        delete tmp[i]; // Calls ~object (which deallocates tmp[i]->foo) 
                       // and deallocates *tmp[i]
      }
      tmp.clear();
    
      return 0;
    }
    
    类对象{
    私人:
    int*foo;
    公众:
    对象():foo(新int()){*foo=42;}
    ~object(){
    //既然foo是动态分配的,那么析构函数
    //需要取消分配它
    删除foo;
    }
    };
    int main(){
    向量tmp;
    tmp.push_back(新对象());
    //用tmp做一些事情
    对于(int i=0;ifoo)
    //和解除分配*tmp[i]
    }
    tmp.clear();
    返回0;
    }
    
    要删除指针末端的对象,请调用delete myVector[i]


    若要从向量中删除该指针,请调用myVector.erase(myVector.begin()+i)

    将类释放其成员所需的内容放入析构函数

    至于向量,它包含指针,而不是对象实例。因此,调用
    erase()
    只会从向量中删除指针,但不会释放指针指向的对象。您必须单独释放对象,例如:

    std::vector<object*> tmp;
    tmp.push_back(new object);
    ...
    std::vector<object*>::iterator iter = ...;
    delete *iter;
    tmp.erase(iter);
    
    std::vector-tmp;
    tmp.推回(新对象);
    ...
    向量:迭代器iter=。。。;
    删除*国际热核实验堆;
    tmp.erase(iter);
    
    您只需调用
    删除tmp[i]。但是我建议使用
    std::vector>

    我编写了这个通用函数模板,它应该可以帮助您:

    template<typename FwdIterator>
    void deleter(FwdIterator from, FwdIterator to)
    {
       while ( from != to ) 
       {
           delete *from;
           from++;
       }
    }
    

    ideone上的演示:

    请您更具体一点,举个例子向量包含指针。erase()将从向量中删除指针,但不会释放指针指向的对象。您必须单独释放该对象。@Remy Lebeau-TeamB,谢谢Remy。。学习STL:)<代码>对象
    ,在您的第二个示例中,缺少一个复制构造函数和赋值运算符。在向量中释放指针需要一个复制构造函数或赋值运算符吗?@Tyler McHenry,我面对同样的问题,在网上搜索了很长一段时间,直到我最终发现了这个宝石般的答案。非常感谢您花时间清楚地阐述这一概念。多亏了这一回应,我成功地解决了我几天来一直面临的一个问题+meDon的1不要使用原始指针作为所有权。使用智能指针。@Tyler McHenry的答案非常好。添加一项:完成
    后删除tmp[i]
    ,您应该执行
    tmp.erase(tmp.begin()+i)
    从向量中删除现在悬空的指针。@aschepper:我认为,在这种情况下,
    tmp.clear()
    tmp.erase(tmp.begin()+I)
    更好。当然,如果一个人想删除所有对象,就像我回答的那样!
    struct object { ~object() { cout << "object deleted" << endl; } };
    
    int main() {
    
            vector<object*> objects;
            objects.push_back(new object());
            objects.push_back(new object());
            objects.push_back(new object());
            objects.push_back(new object());
            objects.push_back(new object());
    
            deleter(objects.begin(), objects.end()); //delete objects
            objects.clear(); //clear the vector
            return 0;
    }
    
    object deleted
    object deleted
    object deleted
    object deleted
    object deleted