Ваш дизайн должен сделать выбор. Либо станьте владельцем и удалите его, либо не становитесь владельцем. В любом случае, пользователь должен знать, как использовать вашу функцию. Им нужно либо знать, что ваша функция уничтожит изображение (и, возможно, передать свою копию по мере необходимости), либо им нужно быть достаточно умным, чтобы управлять собственными ресурсами.
Как правило, вы не хотите лишать права собственности только для того, чтобы удалить ее. Поэтому я бы не ничего удалял. Если кто-то достаточно глуп, чтобы потерять возможность удалить передаваемое изображение, проблема не в этой функции. Другими словами, вы должны попытаться защититься от Мерфи, но забыть о защите от Макиавелли.
Тем не менее, использование необработанного указателя - это плохо! Плохой код C ++ отмечен ручным управлением ресурсами и проблемами с ресурсами. У вас должна быть оболочка вокруг изображения, которая удалит изображение в деструкторе. Таким образом вы можете никогда избежать утечки, даже если возникнет исключение. Предоставьте ему метод reset()
, который отбрасывает старый ресурс изображения и получает новый.
Похоже, вам нужно совместное владение, поэтому вам понадобится оболочка ресурса с подсчетом ссылок. Затем проблема решается: если кто-то выполняет «встроенное» распределение, оно будет помещено в общий указатель, а затем автоматически удалено, когда это будет выполнено. (А еще лучше иметь explicit
конструктор, чтобы кто-то знал, что он будет делиться ресурсом.)
Это делается в умном указателе shared_ptr
. у Boost1 один, а в C ++ 0x есть один. Просто дайте ему пользовательское удаление (которое освобождает изображение), и вы больше никогда не будете беспокоиться об управлении ресурсами.
Это должно быть сделано со всеми ресурсами. Здесь используется концепция Управление ресурсами с привязкой к определенному объему < / а> (SBRM); что ресурс управляется автоматически с использованием правил времени существования автоматических (стековых) переменных. Он известен также как оригинальное, но более уродливое название Инициализация получения ресурсов а> (RAII). Изучите эту область, и вы обнаружите, что ваш код проще и чище.
Это невозможно сделать без изменения типа параметра. Вы можете изменить его на:
void Foo(myClass*& bar);
Поскольку неконстантная ссылка может быть привязана только к lvalue:
void foo(int*&);
int main(void)
{
int *i = 0;
int j;
foo(i); // well-formed
foo(&j); // ill-formed
foo(new int); // ill-formed
}
Однако это запрещает получение адреса lvalue. Конечно, вы можете сделать простое:
int main(void)
{
int j;
int* pj = &j;
foo(pj); // well-formed
}
И это работает. Но я не знаю, зачем вам это нужно.
Вышеупомянутое решение позволит вам изменить аргумент (потому что это ссылка). Если вы хотите принудительно использовать константу внутри функции, вы можете создать такую утилиту:
template <typename T>
class require_lvalue
{
public:
require_lvalue(T& pX) :
mX(pX)
{}
const T& get(void) const
{
return mX;
}
operator const T&(void) const
{
return get();
}
private:
// non-copy-assignable
require_lvalue& operator=(const require_lvalue&);
const T& mX;
};
void foo(require_lvalue<int*>);
Тот же результат, за исключением того, что у вас есть константная ссылка внутри функции.
Обратите внимание, что в MSVC есть ошибка, и он принимает это:
foo(new int);
в обоих случаях, хотя и не должно. (Однако он не принимает new int()
.)
person
GManNickG
schedule
15.08.2010