Как удалить объект, который был разыменован? - PullRequest
0 голосов
/ 19 августа 2011

У меня есть следующий код

MyObject * func1() {
    MyObject * obj = new MyObject();
    // lots of stuff here
    return obj;
}

MyObject func2() {
    MyObject * obj = func1();
    // even more stuff here
    return *obj;
}

void main() {
    MyObject obj = func2()
}

Как я получил от здесь этот код протекает.Будет ли это:

MyObject * func1() {
    MyObject * obj = new MyObject();
    // lots of stuff here
    return obj;
}

MyObject func2() {
    MyObject * obj = func1();
    // even more stuff here
    MyObject obj_r(*obj);
    delete obj;
    return obj_r;
}

void main() {
    MyObject obj = func2()
}

решить проблему?Или есть другие хорошие решения?

в b4: нет, я не могу сделать это ссылкой с самого начала, поскольку func1 () в некоторых случаях возвращает NULL.комментарии, чтобы люди не думали, что я по-королевски глупый

Ответы [ 7 ]

4 голосов
/ 19 августа 2011

Более элегантным решением (и более «правильным») было бы использование умного указателя:

MyObject func2()
{
    return *std::auto_ptr<MyObject>(func1());
}

(Для более современного компилятора используйте std::unique_ptr. Или, если вы используете Boost, вы также можете использовать boost::scoped_ptr.)

Я говорю больше "правильно", потому что если конструктор копирования MyObject выдает исключение, это решение все равно удалит объект, который, как и ваш, будет утечкой.

1 голос
/ 19 августа 2011

Лучший способ избежать утечки памяти - использовать умный указатель:

#include <memory>

MyObject func2() {
    std::unique_ptr<MyObject> obj(func1());
    // stuff here
    return *obj;
}

int main() {
    MyObject obj = func2();
}

Это почти то же самое, что и ваше решение, но исправляет утечку памяти, которая возникает у вас, если во время исключениякопировать объект или делать "вещи".Если вы не используете C ++ 11, используйте auto_ptr вместо unique_ptr.

1 голос
/ 19 августа 2011

Да, это устранит утечку памяти.

Это не очень хорошая картина, в общем. Но тогда я не уверен, чего вы здесь добиваетесь!

0 голосов
/ 19 августа 2011

Если вы не уверены, вернет ли func1 действительный объект или нет, вместо возврата указателя, boost::optional может быть уместным - это позволит func2 проверить, вернул ли func1 что-то действительноебез необходимости выделять что-либо динамически.

0 голосов
/ 19 августа 2011

ИМХО, лучший способ для этого - удалить объект в func1, если ему нужно удалить NULL. В func2, если мы получили нулевой указатель, мы не можем разыменовать его любым способом.

0 голосов
/ 19 августа 2011

Да, ваше второе решение решит проблему за счет большего количества копий.

Мой вопрос: почему вы хотите разместить объект в куче (с новым) просто для копирования?это стеку выделенного объекта, и сразу после этого удалите его.Почему бы вам не создать его просто в стеке в начале?

Вы можете написать это следующим образом:

void main() {
    MyObject obj;
}

В конце вы получите точно такой же результат.И было бы намного проще!

0 голосов
/ 19 августа 2011

Просто измените func2() на это:

MyObject func2() { return MyObject(); }

Динамическое распределение совершенно бесполезно в вашем случае.

...