Чтобы избежать необходимости использовать ->
и вместо этого работать непосредственно с объектом, допустимо ли это делать:
obj x = *(new obj(...));
...
delete &obj;
Чтобы избежать необходимости использовать ->
и вместо этого работать непосредственно с объектом, допустимо ли это делать:
obj x = *(new obj(...));
...
delete &obj;
Это не просто плохая практика, но:
obj
будет хранить копию исходного объекта, созданного выражением new
, и указатель на этот объект, возвращенный new
, будет потерян;delete
указатель на объект, который не был выделен new
. В пункте 5.3.5/2 стандарта С++ 11:[...] В первом альтернативе (удалить объект) значение операнда удаления может быть нулевым указателем value, указатель на объект без массива, созданный предыдущим новым выражением, или указатель на подобъект (1.8) представляющий базовый класс такого объекта (п. 10). Если нет, поведение undefined.
Нет, и на самом деле это приводит к утечке. x
копируется инициализировано, поэтому исходный объект, на который указывает new obj
, теряется.
Просто используйте
obj x(...);
Нет необходимости динамического выделения. Или
obj x = obj(...);
если вы должны (сомневайтесь).
Конечно, нет; который копирует динамический объект в автоматическую переменную, теряет единственный указатель на него, а затем пытается удалить автоматическую копию. У вас есть утечка памяти и неправильное удаление.
Намного лучше было бы использовать автоматическую переменную в первую очередь:
obj x(...);
...
// no need to delete anything
или, если по какой-то причине он действительно должен быть динамическим (потому что он слишком велик для стека, или вы не всегда хотите его уничтожить), затем используйте умный указатель и ссылку, t like ->
std::unique_ptr<obj> p(new obj(...));
obj & x = *p;
...
// still no need to delete anything
Изменение вашего x
в ссылке будет действительным (если вы будете осторожны, что исключения, ранняя функция возвращается и т.д. не вызовет утечку), но вызовет вопли путаницы среди всех, кому не хватает должны поддерживать его.
Вы не можете удалить свой объект должным образом, если вы это сделаете.
Неявно вы делаете следующее.
class A
{
public:
int test (void) { return 1; }
};
int main (void)
{
A * p = new A;
A v(*p);
//...
delete &v; // &v != p and v is not constructed via new!
return 0;
}
Если вы хотите работать с похожим на объект синтаксисом, вы можете привязать ссылку к объекту.
class A
{
public:
int test (void) { return 1; }
};
int main (void)
{
A * p = new A;
A & r = *p;
int i = r.test();
delete p;
return 0;
}
Если вы удаляете свой объект с помощью одного и того же указателя, утечки не будет.