Деструктор c++

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by LibertyPaul, 9 May 2012.

  1. LibertyPaul

    LibertyPaul New Member

    Joined:
    16 Jan 2010
    Messages:
    36
    Likes Received:
    0
    Reputations:
    0
    Если в деструкторе не прописывать уничтожение полей объекта, компилятор сам подставит команды удаления? или будет утечка?

    пример:
    PHP:
    class A{
      public:
      
    int abc;
      
    A(){
        
    a=b=c=0;
      }
      
      ~
    A(){
        
    cout<<"blablabla";
      }
    };
    при создании объектов в int main динамически:
    A *ptr=new A;
    и последующем вызове деструктора, уничтожатся ли объекты в куче, или деструктор просто скажет блаблабла и ничего не освободит?

    Если все-таки надо вручную прописывать освобождение, то будет ли верным вариант :

    PHP:
    ~A(){
    delete &a;
    delete &b;
    delete &c;
    }

    Студент заранее благодарен.
     
  2. GRRRL Power

    GRRRL Power Elder - Старейшина

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84
    Ты на плюсах пишешь, а не на сишнике, тут вызываются деструкторы у всех вложенных объектов автоматически. Деструктор также освобождает память, которую объект занимает, будь он в стеке или в куче, руками ничего освобождать не надо. Вообще, проще было бы самому проверить, а не создавать тему:

    PHP:
    #include <iostream>

    class a
    {
    public:
        ~
    a()
        {
            
    std::cout << "a deleted" << std::endl;
        }
    };

    class 
    b
    {
    public:
        ~
    b()
        {
            
    std::cout << "b deleted" << std::endl;
        }

        
    a obj;
    };


    int main()
    {
        
    b obj;
        return 
    0;
    }
     
    1 person likes this.
  3. GRRRL Power

    GRRRL Power Elder - Старейшина

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84
    Впрочем, нужно удалять ту память, которую руками выделил в куче:
    PHP:
    class b
    {
    public:
        
    b()
        {
            
    memory_ = new char[10]; //создали руками и записали в обычный указатель, надо будет удалить в деструкторе
        
    }

        ~
    b()
        {
            
    delete[] memory_;
        }

    private:
        
    charmemory_;
    };
    Хотя это не слишком-то правильно - можно забыть ее удалить, и такой метод небезопасен по отношению к исключениям. Поэтому проще всего использовать смартпоинтеры, которые сами удалят объект, который больше не нужен, например, так:

    PHP:
    #include <boost/shared_array.hpp>

    class b
    {
    public:
        
    b()
        {
            
    memory_.reset(new char[10]);
        }

    private:
        
    boost::shared_array<charmemory_;
    };
    Тут я использовал класс из библиотеки boost, который позволяет обернуть голый указатель, считает количество ссылок на него (если ты раскопировал класс в 10 экземпляров, на него будет 10 ссылок), и удаляет, когда количество ссылок достигает нуля. Поэтому деструктор тут уже не требуется.

    В любом случае, когда работаешь с голыми указателями (как в первом примере) либо со смартпоинтерами (как во втором), придется продумывать конструктор копирования для класса, так как он, скорее всего, будет делать по умолчанию не совсем то, что будет требоваться. В первом примере его лучше вообще запретить, так как при копировании произведется просто почленное копирование класса, и в итоге память по указателю memory_ будет удалена два раза.
     
    #3 GRRRL Power, 9 May 2012
    Last edited: 10 May 2012