Digamos que tengo una struct "s" con una variable de miembro de puntero int "i". Asigno memoria en el montón para i en el constructor predeterminado de s. Más tarde, en alguna otra parte del código, paso una instancia de s por valor a alguna función. ¿Estoy haciendo una copia superficial aquí? Supongo que no implementé ningún constructor de copias ni operadores de asignación ni nada por s ... solo el constructor predeterminado.Pregunta sobre copia superficial en C++
Respuesta
Para hacer un seguimiento de lo que @ [don.neufeld.myopenid.com] dijo, no es solo una copia superficial, sino que es (elija) una pérdida de memoria o un puntero colgante.
// memory leak (note that the pointer is never deleted)
class A
{
B *_b;
public:
A()
: _b(new B)
{
}
};
// dangling ptr (who deletes the instance?)
class A
{
B *_b;
public:
A()
... (same as above)
~A()
{
delete _b;
}
};
Para resolver esto, hay varios métodos.
Implemente siempre un constructor de copias y operator = en clases que usan punteros de memoria sin formato.
class A
{
B *_b;
public:
A()
... (same as above)
~A()
...
A(const A &rhs)
: _b(new B(rhs._b))
{
}
A &operator=(const A &rhs)
{
B *b=new B(rhs._b);
delete _b;
_b=b;
return *this;
};
Huelga decir que esto es un gran dolor y hay un buen número de sutilezas para hacerlo bien. Ni siquiera estoy totalmente seguro de haberlo hecho aquí y lo he hecho algunas veces. No olvide que debe copiar todos los miembros; si agrega algunos nuevos más adelante, ¡no olvide agregarlos también!
Realice el constructor de copia y el operador = privado en su clase. Esta es la solución de "bloquear la puerta". Es simple y efectivo, pero a veces es sobreprotector.
class A : public boost::noncopyable
{
...
};
Nunca use punteros primas. Esto es simple y efectivo. Hay un montón de opciones aquí:
- clases de uso de cadenas en lugar de punteros de char primas
- uso std :: auto_ptr, impulsar :: shared_ptr, boost :: scoped_ptr etc
Ejemplo:
// uses shared_ptr - note that you don't need a copy constructor or op= -
// shared_ptr uses reference counting so the _b instance is shared and only
// deleted when the last reference is gone - admire the simplicity!
// it is almost exactly the same as the "memory leak" version, but there is no leak
class A
{
boost::shared_ptr<B> _b;
public:
A()
: _b(new B)
{
}
};
Sí, es una copia superficial. Ahora tiene dos copias de s (una en la persona que llama, una en la pila como parámetro), cada una de las cuales contiene un puntero al mismo bloque de memoria.
Usted tendrá dos copias de la s
estructura, cada uno de los cuales tendrá su propio puntero i
, pero ambos i
punteros tendrá el mismo valor que apunta a la misma dirección en la memoria - así que sí, será una copia superficial .
- 1. copia profunda vs copia superficial
- 2. std vector C++ - copia profunda o superficial
- 3. copia superficial de un hashset
- 4. copia superficial de un mapa en Java
- 5. ArrayList copia superficial iterar o clonar()
- 6. Pregunta sobre const_cast en C++
- 7. pregunta sobre? y: en C++
- 8. Pregunta sobre C# covarianza
- 9. clone(): ArrayList.clone() pensé hace una copia superficial
- 10. ¿Cómo mejorarías esta clase de copia superficial?
- 11. ¿SqlCommand.Clone() crea una copia profunda o una copia superficial?
- 12. C: Haciendo una copia profunda de una estructura ... haciendo una copia superficial de una estructura
- 13. Pregunta sobre la optimización en C++
- 14. Pregunta sobre C++ clase interna
- 15. Pregunta sobre C#, servidores, XML
- 16. C++ copia-constructo constructo-y-asignar pregunta
- 17. Pregunta sobre punteros y cadenas en C
- 18. Nuevo en C++. Pregunta sobre punteros constantes
- 19. Pregunta sobre llamadas ambiguas en C#
- 20. Pregunta sobre la herencia múltiple en C++?
- 21. copia profunda en C#
- 22. pregunta sobre la función que devuelve una referencia en C++
- 23. ¿Scala AnyRef.clone realiza una copia superficial o profunda?
- 24. qué es una copia superficial de la matriz
- 25. MongoDB C#: Pregunta sobre la paginación
- 26. Pregunta sobre C# 4.0 genéricos de covarianza
- 27. Pregunta sobre Cyclone
- 28. Comprender dict.copy() - superficial o profundo?
- 29. pregunta general sobre Ruby
- 30. Pregunta sobre eventos personalizados
Su operador de asignación no es una excepción segura. Consulte la pregunta reciente sobre seguridad de copia y excepciones: http://stackoverflow.com/questions/214891/checklist-for-writing-copy-constuctor-and-assignment-operator-in-c#214966 –
Doh, vale, lo arreglé . Ya ves lo que quiero decir sobre que es un dolor y es difícil de conseguir, entonces eh –
La mejor manera de hacer que el constructor de copia y el operador = privado sea heredar de boost :: noncopyable. Debe hacer eso para cada clase a menos que sepa con certeza que se podrá copiar. – CesarB