2016-10-08 5 views
-1
sf::RectangleShape* operator()() 
{ 
    return &player; 

} // RectangleShape Getter 

Нужно ли мне освобождать память после этого геттера? Если да, как это сделать с unique_ptr?Сделать указатель Getter use unique_ptr

Я попытался

std::unique_ptr<sf::RectangleShape> operator()() 
{ 
    return std::unique_ptr<sf::RectangleShape>(player); 

} // RectangleShape Getter 

Но он говорит, что нет функции соответствия для оператора скобки. Как еще это сделать?

+0

Уникальный указатель должен быть либо возвращен из 'make_unique', либо иначе построен из значения выражения' new'. –

+4

Что такое 'игрок'? – Galik

+0

'player', похоже, не является указателем, так как вы берете его адрес в первом примере – krzaq

ответ

0
sf::RectangleShape* operator()() 
{ 
    return &player; 

} // RectangleShape Getter 

Do I need to free memory after this getter?

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

В частности, это означает, что это плохая идея:

struct Foo { 
    sf::RectangleShape player; 
    // ... 
    // insert your operator here 
}; 

sf::RectangleShape * some_function(void) { 
    Foo f; 
    return f(); // UB, returning pointer to object with automatic memory whose lifetime has ended 
} 

[..] how would one do this with unique_ptr?

Предполагая sf::RectangleShape имеет конструктор копирования, то вы можете сделать копию player:

std::unique_ptr<sf::RectangleShape> operator()() { 
    return make_unique<sf::RectangleShape>(player); 
} 

Копия вы получаете этот путь «ваш», то есть вы можете управлять жизнью, как хотите.

+0

Итак, если я использую 'make_unique', он делает копию или это тот же объект с теми же свойствами? – kim366

+0

Это копия. Конечно, предполагается, что объекты этого типа фактически * могут * копироваться. –

+0

Хорошо, так что метод не является жизнеспособным, поскольку он должен быть одним и тем же объектом. Спасибо! – kim366

1

Похоже, что player является членом класса, и вы пытаетесь передать указатель на него для его изменения вне класса?

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

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

class SomeClass 
{ 
    sf::RectangleShape player; 
    sf::RectangleShape& operator()() 
    { 
     return player; 
    } 
}; 

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

+0

Ваше предположение верно, и единственная причина, по которой я использую указатель на ссылку, заключается в том, что для класса более ясно, что это не копия, а действительно переменная-член и что ее следует обрабатывать осторожно. Насколько я понял, вам нужно только заботиться об управлении памятью при создании переменной указателя или использовании ключевого слова 'new'. Это верно? – kim366

+1

Вы должны беспокоиться о освобождении памяти всякий раз, когда есть динамическое распределение памяти, например. используя 'new' или любой из вариантов' alloc' C-стиля. Они традиционно используются, если ресурс создается внутри и возвращается из функции, или объект слишком велик, чтобы выделять непосредственно в стеке. В этих случаях часто бывает лучше создать 'unique_ptr' (через функцию' make_unique'), так как ресурс затем автоматически очищается, когда ptr выходит за рамки. Вы можете использовать функцию 'ptr.get()', чтобы получить необработанный указатель, который может быть передан ... далее ... – djrollins

+1

, так что другие могут изменять ресурс. Но они не должны пытаться освободить его. Указатели по сути не означают распределение динамической памяти - например, вы можете создать указатель на стек. Поэтому вам действительно нужно подумать о том, кто ** владеет ** объектом и где он выделен. Вот почему интеллектуальные указатели рекомендуются по сравнению с необработанными указателями, потому что вы неявно предоставляете ресурс на всю жизнь на основе прав собственности, и поэтому не нужно беспокоиться о освобождении памяти. Вам все равно нужно быть осторожным, чтобы обмануть необработанные указатели на данные 'unique_ptr' после того, как он освобожден. – djrollins

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

  • Нет связанных вопросов^_^