2011-12-23 10 views
5

En mi clase tengo dos miembros privados:¿Puedo obtener un puntero a un valor repetidor actual

std::list<MyObject> objects; 
MyObject *selecteObj; 

Cuando se produce un evento que me gustaría recorrer la lista y ejecutar algún tipo de prueba que se solo rinde verdadero en uno de los artículos en la lista. Me gustaría guardar un puntero a ese elemento para usarlo en otro lugar.

std::list<MyObject>::iterator i; 
for (i = objects.begin(); i!=objects.end(); ++i){ 
    if (i->test()) 
     selectedObj = i; 
} 

Otras ligas En otro método

if (selectedObj !=null) 
    tmpObj->doSomething(); 

Sin embargo, esto no funciona porque i no es un puntero, su un iterador a pesar de que se puede tratar como un puntero a un MyObject.

¿Es posible recuperar el puntero que el iterador está almacenando internamente para su uso en otro lugar?

¿Estoy pensando en esto incorrectamente?

¿Cuál es la forma correcta de lograr lo que estoy tratando de hacer?

Respuesta

12

¿Es posible recuperar el puntero que el iterador está almacenando internamente para su uso en otro lugar?

Claro, sólo eliminar la referencia al iterador con * y luego obtener un puntero al objeto a través de &:

selectedObj = &*i; 

En una nota lateral, ¿recuerda haber inicializar selectedObj con NULL antes del bucle?

+1

Seguramente quiere decir 'std :: addressof (* i)', ¿no es así? El OP no preguntó cómo invocar el operador '&' del objeto ... –

+0

@KerrekSB: Creo que quisiste decir 'std :: addressof' (en lugar de' std :: address_of'), ¿no? : P – Nawaz

+0

@Nawaz: oh, ¿qué dije * I *? ;-) –

6

¿Es posible recuperar el puntero que el iterador está almacenando internamente para su uso en otro lugar?

Sí. Como dijo @FredOverflow, hacer esto:

selectedObj = &*i; 

Sin embargo, si se puede utilizar características de C++ 11, a continuación, se puede disfrutar de una mejor escribir la sintaxis usando for bucle basado en la gama como:

MyObject *selectedObj = NULL; 
for (MyObject & obj : objects) 
{ 
    if (obj.test()) 
     selectedObj = &obj; //store the address 
} 

¿Se ve mejor? No es necesaria la sintaxis de iterador y escritura como &*i. También se debe tener en cuenta que si la clase MyObject ha sobrecargado operator &, entonces &*i no funcionaría, ya que invocaría la función operator&, ¡en lugar de obtener la dirección del objeto! Si es así, entonces usted tiene escribir (MyObject*)&(char&)*i para obtener la dirección de *i, o en C++ 11 puede utilizar std::addressof(*i) que puede definir usted mismo si no puede utilizar C++ 11:

template< class T > 
T* addressof(T& arg) { 
    return (T*)&(char&)arg; 
} 

Código tomado de aquí: std::addressof

Cuestiones relacionadas