2012-07-03 3 views
1

У меня есть переменная, на которую много ссылок. Он начинался как автоматическая переменная.Использование ручного управления памятью со ссылкой?

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

До:

void func() { 
    ClassName varname; 
    while (varname.check()/*...*/) { if (varname.function()/*...*/) { /* bunches of code ... */ 
      /*... some more code ... */ 
     } 
    } 
} 

Теперь я хочу:

void func() { 
    ClassName varname; 
    while (varname.check()/*...*/) { if (varname.function()/*...*/) { /* bunches of code ... */ 
      if (key_code[SDLK_r]) { // Pressing R key should reset "varname"! 
       /* Here I want to dealloc and realloc varname! */ 
       /* But if I declare varname as a ptr on line 2, */ 
       /* line 3 (rest of code) must be refactored. */ 
      } 
     } 
    } 
} 

Моя первая попытка пойти изменить линию 2, чтобы быть что-то вроде этого

ClassName *varnamep = new ClassName(); 
ClassName& varname = *varnamep; 

Но я не конечно, если это означает, что я смогу позже называть delete и переназначить ссылку!

   delete &varname; 
       varnamep = new ClassName(); 
       varname = *varnamep; // I assume compiler will error here because I can't reassign a ref. 

Могу ли я сделать это по-другому? Или я должен просто сосать его и сделать find-replace для поворота varname. в varname->? В этом конкретном случае для моей реальной реальной ситуации я, вероятно, реализую функцию-член reset() и не волнуюсь об этой актуальной проблеме. Но я хотел бы знать, если есть ярлык, чтобы быть в состоянии эффективно обрабатывать ссылки в качестве указателей (или может оказаться, что это абсурд нонсенс)

ответ

2

Стандартный путь не удалить и создать новый экземпляр , Просто переназначить переменную:

ClassName varname = .... ; 

.... 

if (some condition) { 
    varname = SomethingElse; 
} 

и убедитесь, что конструктор копирования, оператор присваивания и деструктор правильно справиться с управлением ресурсами ClassName.

+0

У меня возникли трудности с поиском ссылок, которые объясняют, что это делает. Исправлен ли исходный выделенный объект в стеке?Я предполагаю, что пространство в стеке просто перерабатывается. Вызывать ли ддор и ctor? –

+1

@StevenLu Ну, ann автоматические переменные освобождаются, когда они выходят за рамки. Существует только один экземпляр «ClassName», и его члены данных копируются, когда переменная переназначается. Я приведу пример [здесь] (http://ideone.com/421Z4), я надеюсь, что это поможет прояснить ситуацию. – juanchopanza

+0

Это действительно здорово, что вы создали этот пример, спасибо. –

4

Учитывая ClassName varname, вы могли сделать это:

varname.~ClassName(); 
new (&varname) ClassName; 

Но я бы не рекомендовал его. Это использует две менее известные функции C++: явный вызов деструктора и размещение нового. Используйте это только в том случае, если он существенно влияет на производительность, как измеряется профилировщиком, а конструктор ClassName не может генерировать исключение.

Если ClassName::operator= делает то, что вам нужно (или вы можете изменить его, чтобы делать то, что вам нужно), вы можете сделать это:

varname = ClassName(); 

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

Еще одна распространенная идиома:

varname.swap(ClassName()); 

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

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