2010-01-18 2 views
2

В книге Страуструпа На языке программирования C++ он упоминает: «Как правило, важно, чтобы ресурсы были выпущены в обратном порядке их приобретения» Почему заказ важен?Зачем нужен порядок управления ресурсами?

void acquire() 
{ 
acquire resource 1; 
... 
acquire resource n; 
use resources; 
release resource n; 
... 
release resource 1; 
} 

так что, если мы изменим порядок, как указано ниже?

void acquire() 
{ 
    acquire resource 1; 
    ... 
    acquire resource n; 
    use resources; 
    release resource 1; 
    ... 
    release resource n; 
} 

ответ

0

ресурсов, в реальном коде, как правило, быть вложенными, и вы хотите что-нибудь доступное при строительстве объекта должны быть доступны при уничтожении его. Поскольку C++ имеет детерминированное разрушение, он должен выбрать некоторый порядок, и FILO («first in, last out») работает хорошо.

Простейшим примером гнездования являются классы. Они всегда построены первыми построения баз, затем члены, затем тело производного CTOR в:

struct Base { 
    Base() { cout << "Base\n"; } 
}; 
struct Member { 
    Member() { cout << "Member\n"; } 
}; 

struct Derived : Base { 
    Member member; 
    Derived() { cout << "Derived\n"; } 
}; 

Теперь вы можете добавить аналогичные выходные dtors этого примеру.

Вы не можете уничтожить базу до того, как Derived был уничтожен (возможно, для его использования может потребоваться использовать dtor Derived, среди прочих проблем); такой же для участник.

4

Если вы этого не сделаете, вы можете попасть в тупик или ситуацию с утечкой. Скажем, что вы объявляете Obj1 и выделяете Obj2-Obj3. У вас должно быть 2 и 3 освобожденных, прежде чем вы сможете освободить 1. На практике, хотя это не о чем беспокоиться, потому что конструкторы и деструкторы будут вызваны в правильном порядке.

3

Одна из причин заключается в том, что вы обычно имеете вложенные распределения памяти.

E.g. you have a class 
class A{ 
    FILE *fp; 
    char *name; 
    xxx; 
} 

сначала выделить ресурс для помощи new A, а затем вам нужно манипулировать и fpname. Поэтому, когда вы отпускаете ресурс, сначала необходимо освободить fp и name, затем A.

1

В самом общем смысле «это имеет значение только в том случае, если это имеет значение». Зависимости диктуют необходимый порядок уничтожения.

Существующие ответы здесь относятся к выпуску вложенных ресурсов в обратном топологическом порядке.

Но также, C++ определяет порядок инициализации ресурсов внутри объекта. Это означает, что конструкция члена может использовать ранее инициализированные «братья и сестры» ... что означает, что они имеют зависимости, и эти братья и сестры все равно должны быть действительны при уничтожении.

class A { 
    A(std::string *link2str); 
    ~A(); 
    std::string *important_state; 
}; 

class B { 
    string first; // initialization occurs in the order of declaration 
    A second; 
    B() : first(), second(&first) { } // not the constructor's list order 
}; 

Не то, чтобы этот пример выглядел как хороший дизайн, но вы никогда не знаете. Иногда есть причина какой-то зависимости между членами.

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