Ventajas de usar std:: hacer único sobre el nuevo operador [duplicar]
Esta pregunta ya tiene una respuesta aquí:
- Diferencias entre std::make_unique y std::unique_ptr 3 respuestas
¿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
?
2 answers
Ventajas
make_unique
enseña a los usuarios "nunca digasnew
/delete
ynew[]
/delete[]
" sin renuncias.make_unique
comparte dos ventajas conmake_shared
(excluyendo la tercera ventaja, mayor eficiencia). Primero,unique_ptr<LongTypeName> up(new LongTypeName(args))
debe mencionarLongTypeName
dos veces, mientras queauto up = make_unique<LongTypeName>(args)
lo menciona una vez.make_unique
previene la orden-de-evaluación-no especificada fuga desencadenada por expresiones comofoo(unique_ptr<X>(new X)
,unique_ptr<Y>(new Y))
. (Siguiendo el consejo "nunca digasnew
" es más simple que "nunca digasnew
, a menos que inmediatamente se lo des a ununique_ptr
nombrado".)make_unique
se implementa cuidadosamente para la seguridad de excepciones y se recomienda llamar directamente a los constructoresunique_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
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
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