2012-03-31 1 views
1

В C++, чья ответственность заключается в том, чтобы удалить члены класса: класс или создатель экземпляра этого класса?
Например, в следующем коде:Чьей ответственностью является удаление

class B { 
    public: 
    B(int x) { num = x; } 
    int num; 
}; 

class A { 
    public: 
    A(B* o) { obj = o; } 
    B* obj; 
}; 

int main(void) { 
    A myA(new B(3)); 
    return 0; 
} 

Если main удалить экземпляр из B или должен деструктор A «s удалить свою локальную переменную obj? Это правда в большинстве случаев, и в каких случаях это возможно?

+2

Это деструктор. Итак, чтобы ответить на вопрос, класс, когда вызывается деструктор. Если вы используете интеллектуальные указатели, ни о чем не стоит беспокоиться. – chris

+1

Это будет ваш выбор дизайна. Единственное принудительное правило таково: ваша программа должна вызывать 'delete' для каждого' нового'. –

ответ

3

Это основной вопрос собственности. Если каждый A должен иметь B (как в случае, должен быть создан новый B, созданный при создании A, который также должен быть уничтожен, будет уничтожен A, тогда вы обычно должны сделать A ответственным за создание и уничтожение экземпляра B:

class B { 
    int num; 
public: 
    B(int x) : num(x) {} 
}; 

class A { 
    B *obj; 
public: 
    A(int value) : obj(new B(value)) {} 
    ~A() { delete B; } 
}; 

В таком случае, однако, шансы очень хорошо, что A просто должны быть написаны как:

class A { 
    B obj; 
public: 
    A(int v) : obj(v) {} 
}; 

int main() { 
    A a(3); 
    return 0; 
} 

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

+0

Не забывайте о Правиле трех. – chris

+0

@chris: yes - часть причины просто сделать это правильно и агрегировать экземпляр B непосредственно в A и делать с ним. –

+0

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

1

Практически всегда A должен управлять своими членами, поскольку это то, на чем основан RAII. Используйте unique_ptr, когда сможете.

Если он не управляет данными, он должен использовать другой умный указатель, в частности shared_ptr. Это переносит ответственность на shared_ptr, что гораздо меньше подвержено ошибкам, чем указатель ванили.

И, конечно, предпочтительный способ - не использовать никаких указателей. Почему вы звоните new?

+1

Почему я называю новое: чтобы задать этот вопрос. Я прихожу на C++ из java и C, и я хочу все понять. Я никогда не слышал о умных указателях или RAII, но я буду искать их. Благодаря! – Robz

+0

@ Robz - В C++ вы почти никогда не называете 'new'. C++ и Java - это * очень разные языки. –

+0

@BoPersson, что вы пишете на C++, что вы почти никогда не называете новым? :) –

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