c++ - sencillos - sobrecarga de operadores poo pdf
Evaluación de una expresión con operadores sobrecargados en c++ lldb (2)
Estoy depurando un programa C ++ en Xcode 5 usando lldb, y me gustaría evaluar expresiones arbitrarias en el depurador, particularmente aquellas que usan operadores sobrecargados.
Por ejemplo, creé un proyecto Xcode 5 C ++ muy simple con el siguiente main.cpp y todas las opciones del compilador / vinculador / etc configuradas en el valor predeterminado:
#include <iostream>
#include <vector>
int main(int argc, const char * argv[])
{
std::vector<int> vec;
vec.push_back(42);
std::cout << "vec[0] = " << vec[0] << std::endl;
return 0;
}
Puse un punto de interrupción en el return 0;
Línea y corrió el programa.
Luego, en el indicador de lldb, la impresión del vector en su conjunto funciona bien:
(lldb) expr vec
(std::__1::vector<int, std::__1::allocator<int> >) $0 = size=1 {
[0] = 42
}
Sin embargo, no puedo acceder a sus miembros utilizando el operator[]
sobrecargado operator[]
:
(lldb) expr vec[0]
error: call to a function ''std::__1::vector<int, std::__1::allocator<int> >::operator[](unsigned long)'' (''_ZNSt3__16vectorIiNS_9allocatorIiEEEixEm'') that is not present in the target
error: The expression could not be prepared to run in the target
Del mismo modo, no puedo obtener el iterador (aunque tengo menos experiencia aquí, por lo que mi sintaxis puede ser incorrecta):
(lldb) expr vector<int>::iterator it = vec.begin()
error: use of undeclared identifier ''vector''
error: expected ''('' for function-style cast or type construction
error: expected ''('' for function-style cast or type construction
error: 3 errors parsing expression
y
(lldb) expr (vector<int>::iterator) vec.begin()
error: use of undeclared identifier ''vector''
error: expected ''('' for function-style cast or type construction
error: expected ''('' for function-style cast or type construction
error: 3 errors parsing expression
Análogamente, imprimir una cadena simple funciona bien:
(lldb) expr string("a")
(std::__1::string) $0 = "a"
Sin embargo, una concatenación de cadena simple falla:
(lldb) expr string("a") + string("b")
error: invalid operands to binary expression (''string'' (aka ''std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >'') and ''string'')
error: 1 errors parsing expression
¿Qué estoy haciendo mal? ¿Admite lldb la evaluación con operadores sobrecargados?
¡Gracias de antemano!
Me encontré con el mismo problema y aparentemente encontré una solución alternativa simple. Puedes acceder al elemento i -ésimo de un vector vec
como este:
(lldb) p vec.__begin_[i]
(int) $1 = 100
Tenga en cuenta que las bibliotecas estándar de C ++ están configuradas de modo que integran todas las funciones de plantilla que pueden en línea con sensatez, y no existen copias de funciones reales. Entonces, por ejemplo, cuando llamas a std::vector<int>::begin()
, no existe tal función. Todos sus usos han sido en línea.
Es por eso que está recibiendo errores acerca de "llamada a función ... no presente en el destino". Puede haber copias en línea de la función, pero no podemos llamar a ninguna. Como ejemplo, si construyo un pequeño programa en C ++ que hace un std :: vector, inserta algunos elementos en él y luego lo repite sobre ellos, y luego hago:
(lldb) image lookup -r -n begin
2 matches found in /private/tmp/vector:
Address: vector[0x0000000100000eaf] (vector.__TEXT.__text + 1071)
Summary: vector`main + 1071 [inlined] std::__1::vector<int, std::__1::allocator<int> >::begin() at vector.cpp:12
vector`main + 1071 at vector.cpp:12 Address: vector[0x0000000100000eaf] (vector.__TEXT.__text + 1071)
Summary: vector`main + 1071 [inlined] std::__1::vector<int, std::__1::allocator<int> >::begin() at vector.cpp:12
vector`main + 1071 at vector.cpp:12
Por lo tanto, todas las instancias de los accesos de inicio y fin para std::vector<int>
están en línea. Y más abajo en la parte que viene de la biblioteca std c en sí:
12 matches found in /usr/lib/libc++.1.dylib:
Address: libc++.1.dylib[0x000000000003e4ec] (libc++.1.dylib.__TEXT.__text + 252188)
Summary: libc++.1.dylib`std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::begin() Address: libc++.1.dylib[0x000000000003e51c] (libc++.1.dylib.__TEXT.__text + 252236)
Summary: libc++.1.dylib`std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::begin() const Address: libc++.1.dylib[0x000000000003e574] (libc++.1.dylib.__TEXT.__text + 252324)
y algunos más para basic_string, y eso es todo. Así que no hay implementaciones reales a las que podamos llamar. Luego, una vez que solo tenemos un poco del mundo real de estos objetos estándar disponibles para nosotros, el mundo se desmorona de otras formas extrañas a medida que empiezas a empujarlo.
Actualmente, lldb no es lo suficientemente inteligente para descubrir cómo reconstituir una función / método con plantilla a partir de los archivos de encabezado de la biblioteca estándar de C ++. No tenemos suficiente del entorno en el que su código fue compilado originalmente para hacer esa tarea.
Tenga en cuenta que esto no es realmente un problema con los operadores sobrecargados, es más un problema con la forma en que el compilador utiliza las bibliotecas estándar. Las cosas deberían funcionar mejor para sus propias clases, donde en -O0 no hay tanta inclinación.