2015-02-21 3 views
1
class B; 
class A 
{ 
    private: 
     unsigned int x; 
     B *m_pParent; 

    public: 
     A(B* parent) : m_pParent(parent) 
     { 
      x = rand(); 
     } 

     ~A() 
     { 
      m_pParent->doCleanup(); 
     } 

     unsigned int getSomeVariable() 
     { 
      return x; 
     } 
} 

class B 
{ 
    private: 
     A* m_pChild; 

    public: 
     B() 
     { 
      m_pChild = new A (this); 
     } 

     void doCleanup() 
     { 
      m_pChild->getSomeVariable(); 
     } 
} 

Таким образом, класс A имеет кучу кода очистки в своем деструкторе, один из которых вызывает функцию класса B с указателем на A, чтобы использовать некоторые из A переменные получают функции в процедуре очистки внутри B.Безопасен ли этот код? Функции вызова из класса, который разрушается

Теперь я знаю, что это не большой дизайн, но с этим я должен работать. Я изучаю некоторые журналы сбоев, и кажется, что это то, что может вызвать крушение. Может ли быть так, или этот код безопасен?


Объект разрушается вне сферы действия обоих классов.

+1

Где находится объект? Я вижу вызов 'new', бит no call to' delete'. – juanchopanza

+0

Извините, что не было ясно, A удаляется за пределами области действия обоих классов, поэтому есть вызов функции очистки B, так что он знает, что объект уничтожается. –

+0

Код, который вы опубликовали, безопасен. Однако я сомневаюсь, что это все (реальный) код, который вы используете, так что все еще могут быть проблемы с тем, как вы действительно делаете что-то. – Cornstalks

ответ

2

Деструктор для A в вашем примере безопасен. Память для A не освобождается, пока деструктор не вернется, и поэтому m_pChild->getSomeVariable() в порядке.

Однако, ваш реальный код может содержать дополнительную очистку в деструкторе для A, которая уничтожает элементы A до m_pParent->doCleanup().

Например, если пример был немного изменен, это:

A(B* parent) : m_pParent(parent) 
{ 
    x = new int(rand()); 
} 

~A() 
{ 
    delete x; 
    m_pParent->doCleanup(); 
} 

unsigned int getSomeVariable() 
{ 
    return *x; 
} 

Теперь, деструктор A не является безопасным, так как getSomeVariable называют doCleanup и x является оборванным указателем на тот момент ,

Трудно сказать, что именно вызывает ваш крах без дополнительной информации. Я бы рекомендовал посмотреть на это в отладчике, если это возможно. Он должен показать вам, где происходит авария.

Редактировать: вы также можете использовать Valgrind для поиска ошибок памяти в Linux, а в Windows есть функция проверки отладки, которую вы можете включить.

+1

Нет, этого не происходит, ни один из его членов не уничтожается до того, как функция очистки заканчивается родительским концом, любые указатели удаляются после того, как функция очистки завершится и вернется к деструктору, но приложение сработает прямо перед тем, как обратиться к нормальной функции переменной get к переменной-члену класса nonpointer, подобной int. –

+0

@SirRogers Включено ли наследование? Если getSomeVariable() определен в производном классе A, то, возможно, производный класс выполняет некоторую очистку, которая делает недействительным состояние объекта. Деструкторы производных классов вызывается перед деструктором базового класса. В любом случае код, который вы указываете в исходном вопросе, безопасен. –

+0

Существует наследование, но ни одна из функций производного класса не вызвана, и ни один из ее членов не доступен. На самом деле это производный класс, который запускает деструктор. Итак, класс A: public D-D имеет функцию setDelete, его жизненный цикл управляется внутри API, и этот API запускает вызов удаления на D *, который затем запускает виртуальный деструктор A. Но снова ни один из D's доступ к элементам осуществляется ни А, ни Б, его чисто переменные А и функции. –

1

Пока деструктор класса выполняется, объект еще не уничтожен. Вы можете вызвать функции-члены из другого класса в деструкторе, которые в свою очередь вызывают методы из уничтожаемого класса.

Однако имейте в виду, что при использовании наследования подклассы будут уничтожены до базовых классов. Поэтому, когда другой класс вызывает любую функциональность, реализованную в подклассе, он будет работать на уже разрушенном объекте, который может иметь непреднамеренные последствия.

Смежные вопросы