2013-07-03 3 views
0

Мне было интересно, как написать оператору =, чтобы освободить существующую выделенную память от переменной.Использование оператора = в сочетании с новым оператором

Например, в приведенном ниже коде при переназначении указателя xx = new ClassExample(4) будет удалена старая память x->a.

По-видимому, при использовании new, оператор = не применяется (это только для уже существующих значений).

Есть ли способ сделать это (свободная старая память при назначении новой памяти)?

#include <iostream> 
#include <cstdlib> 

class ClassExample { 
public: 
    int* a; 
    ClassExample& operator= (const ClassExample& rightSide) { 
     //..... 
    } 

    ClassExample(int val) { 
     a = new int(val); 
    } 
}; 

int main() 
{ 
    ClassExample* x = new ClassExample(2); 
    x = new ClassExample(4); 
    return 0; 
} 
+0

В этом случае оператор назначения не вызывается, потому что вы используете указатели, а не прямые экземпляры. А также помните, что выделенная память никогда не будет автоматически бесплатной, вы должны это сделать. Использование [умных указателей] (http://en.cppreference.com/w/cpp/memory/shared_ptr) помогает. –

+0

На самом деле, в таком случае, * почему * вы используете указатели? И я имею в виду не только указатели ClassExample в 'main', но и указатель участника' a' в классе! Правила, которым вы должны следовать, следующие: 1. Не используйте указатели. 2. Если вам нужно использовать указатели, не делайте этого. 3. Если вам все еще нужно использовать указатели, используйте интеллектуальные указатели. –

+0

Подумайте о безопасности исключений – doctorlove

ответ

2

Никогда не нарушить это правило: каждый new должен быть сбалансирован с delete.

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

Вкратце, вы создаете класс WrappedPtr<T> шаблона для типа данных T, который держит T* указателя. В качестве отправной точки вы можете определить оператор присваивания, который удалит текущий обернутый объект, прежде чем принимать новый в качестве своих данных-членов. Вам нужно будет позаботиться о создании копии; или даже запретить это.

Настоящий умный указатель также каким-то образом реализует подсчет ссылок.

См http://www.boost.org/doc/libs/1_54_0/libs/smart_ptr/shared_ptr.htm

0

Оператор = означает, что вы изменяете значение внутри текущего объекта. Здесь вы просто меняете указатель x.

, как вы могли бы сделать это:

ClassExample x(2); 
x = ClassExample(4); 

Или, в вашем случае, что-то вроде:

ClassExample* x = new ClassExample(2); 
*x = *(new ClassExample(4)); 

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

ClassExample* x = new ClassExample(2); 
*x = ClassExample(4); 

Это один не будет течь.

+0

Это может не вызвать утечку val, но вызов new должен быть согласован путем вызова delete, иначе он будет * течь – doctorlove

+0

Нет проблем с моим последним примером, первый «ClassExample (2)» все еще будет существовать , и «ClassExample (4)» будет уничтожен после завершения копирования. Затем, конечно, «x» нужно будет удалить до конца программы. – Uman