Ventajas de usar std:: hacer único sobre el nuevo operador [duplicar]


Esta pregunta ya tiene una respuesta aquí:

¿Cuáles son las ventajas de usar std::make_unique sobre el operador new para inicializar un std::unique_ptr?

En otras palabras, ¿por qué es

std::unique_ptr<SomeObject> a = std::make_unique(SomeObject(...))

Mejor que hacer

std::unique_ptr<SomeObject> a = new SomeObject(...)

Intenté buscar mucho en línea y lo hago sepa que es una buena regla general evitar el operador new en C++ moderno, pero no estoy seguro de cuáles son las ventajas en este escenario exacto. ¿Previene cualquier tipo de pérdida de memoria que pueda ocurrir? ¿Es más rápido hacer un std::make_unique que usar new?

Author: Cris Luengo, 2016-05-29

2 answers

Ventajas

  • make_unique enseña a los usuarios "nunca digas new/delete y new[]/delete[]" sin renuncias.

  • make_unique comparte dos ventajas con make_shared (excluyendo la tercera ventaja, mayor eficiencia). Primero, unique_ptr<LongTypeName> up(new LongTypeName(args)) debe mencionar LongTypeName dos veces, mientras que auto up = make_unique<LongTypeName>(args) lo menciona una vez.

  • make_unique previene la orden-de-evaluación-no especificada fuga desencadenada por expresiones como foo(unique_ptr<X>(new X), unique_ptr<Y>(new Y)). (Siguiendo el consejo "nunca digas new" es más simple que "nunca digas new, a menos que inmediatamente se lo des a un unique_ptr nombrado".)

  • make_unique se implementa cuidadosamente para la seguridad de excepciones y se recomienda llamar directamente a los constructores unique_ptr.

Cuando no usar make_unique

  • No use make_unique si necesita un deleter personalizado o está adoptando un puntero raw de otro lugar.

Fuentes

  1. Propuesta de std::make_unique.
  2. Herb Sutter's GotW # 89 Solución: Punteros inteligentes
 47
Author: 101010,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-29 20:54:52

La diferencia es que std::make_unique devuelve un objeto de tipo std::unique_ptr y new devuelve un puntero al objeto creado. Para errores de asignación de memoria, ambos lanzarán. Espera, no es tan simple. Leer más.

Considere esta función a continuación:

void func(ClassA* a, ClassB* b){
     ......
}

Cuando haces una llamada como func(new A(), new B()); El compilador puede elegir evaluar los argumentos de la función de izquierda a derecha, o en cualquier orden que desee. Asumamos de izquierda a derecha evaluación: ¿Qué sucede cuando la primera expresión new tiene éxito pero la segunda expresión new se lanza?

El verdadero peligro aquí es que al atrapar la excepción; Sí, usted puede haber tomado la excepción lanzada por new B(), y reanudar la ejecución normal, pero new A() ya sucedió, y su memoria será en silencio se filtró. Nadie que lo limpie... * sollozos...

Pero con make_unique, no puedes tener una fuga porque, el desenrollamiento de la pila ocurrirá ( y el destructor de la se ejecutará el objeto previamente creado). Por lo tanto, tener una preferencia por make_unique te limitará hacia seguridad de excepción. En este caso, std::make_unique proporciona un "Seguridad Básica de Excepción" que la memoria asignada y el objeto creado por new nunca quedarán huérfanos pase lo que pase. Hasta el fin de los tiempos... :-)

Deberías leer Herb Sutter GoTW102

 21
Author: WhiZTiM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-30 12:10:47