2011-02-08 9 views
11

Así, después de investigar todas partes por ella, me parece que no puede encontrar la forma de crear un operador de flecha de la clase, es decir,¿Cómo creo y uso un operador de flecha de clase?

class Someclass 
{ 
    operator->() /* ? */ 
    { 
    } 
}; 

sólo hay que saber cómo trabajar con él y utilizar de manera apropiada. - ¿Cuáles son sus entradas? - ¿Qué devuelve? - ¿cómo lo declaro/prototipo?

+3

sin entradas. El tipo de devolución debe ser un puntero. Esto generalmente se usa para crear punteros "inteligentes", por lo que devuelve un puntero al objeto envuelto. – Tim

Respuesta

14

El operador -> se utiliza para sobrecargar el acceso de miembros . Un pequeño ejemplo:

#include <iostream> 
struct A 
{ 
    void foo() {std::cout << "Hi" << std::endl;} 
}; 

struct B 
{ 
    A a; 
    A* operator->() { 
     return &a; 
    } 
}; 

int main() { 
    B b; 
    b->foo(); 
} 

Este salidas:

Hi 
+0

¿el operador de flecha también trabaja para devolver miembros de estructura como lo hace miembros de clase? – Codesmith

+0

Puede devolver miembros de estructura tan fácilmente como puede devolver miembros de clase. Lo que sucede cuando usas la flecha está determinado por el cuerpo del operador ->() función de miembro. La línea "return & a;" puede cambiarse para devolver lo que usted decida que sea apropiado. – Darryl

0

La "flecha" operador puede sobrecargarse por:

a->b 

se traducirán a

return_type my_class::operator->() 
+0

No es tan fácil, 'return_type {} ->() ->() ->() ... ->()' tiene que ser un puntero para que este sea un código válido. – alfC

16

El operador flecha no tiene entradas. Técnicamente, puede devolver lo que quieras, pero debería devolver algo que sea un puntero o bien un puntero through chained -> operators.

El operador -> desreferencias automáticamente su valor de retorno antes de llamar a su argumento utilizando el incorporado en referencia a un puntero, no operator*, lo que podría tener la clase siguiente:

class PointerToString 
{ 
    string a; 

    public: 
    class PtPtS 
    { 
     public: 
     PtPtS(PointerToString &s) : r(s) {} 
     string* operator->() 
     { 
      std::cout << "indirect arrow"; 
      return &*r; 
     } 
     private: 
     PointerToString &r; 
    }; 

    PointerToString(const string &s) : a(s) {} 
    PtPts operator->() const 
    { 
     std::cout << "arrow dereference\n"; 
     return *this; 
    } 
    string &operator*() const 
    { 
     std::cout << "dereference\n"; 
     return a; 
    } 
}; 

usarlo como:

PointerToString ptr(string("hello")); 
string::size_type size = ptr->size(); 

que es convertida por el compilador en:

string::size_type size = (*ptr.operator->().operator->()).size(); 

(con el mayor número .operator->() como sea necesario para devolver un puntero real) y debe de salida

arrow dereference 
indirect dereference 
dereference 

Nótese, sin embargo, que usted puede hacer lo siguiente:

PointerToString::PtPtS ptr2 = ptr.operator->(); 

De Stroupstrup:

La transformación del objeto p en el puntero p.operator->() no depende del miembro m apuntado a. Ese es el sentido en el que operator->() es un operador de un solo sufijo. Sin embargo, no se ha introducido una nueva sintaxis, por lo que aún se requiere un nombre de miembro después de ->

+0

No hay forma de que este código se compile en un compilador decente. –

+0

@SebastianRedl, estás en lo correcto. He actualizado la explicación y el ejemplo para que compile. –

Cuestiones relacionadas