Pregunta

Esta pregunta ya tiene una respuesta aquí:

Mi problema es simple. Tengo una plantilla de clase que contiene un puntero a un tipo asignado dinámicamente. Quiero sobrecargar el operador de indirección para que referirme a la instancia de plantilla de clase con el operador -> Me redirigen como si utilizo el puntero contenido directamente.

template<class T>
class MyClass
 {
  T *ptr;
  ...
  // created dynamic resource for ptr in the constructor
 };

Crea myClass de algún tipo:

MyClass<SomeObject> instance;

Entonces, lo que quiero es en lugar de tener que escribir:

instance.ptr->someMemberMethod();

Simplemente escribo:

intance->someMemberMethod();

Incluso tú instance no es un puntero que se comporta como si fuera el puntero instance contiene. ¿Cómo cerrar esa brecha sobrecargando el operador?

¿Fue útil?

Solución

Solo puedes sobrecargar operator-> y operator*:

template<class T>
class MyClass
{
    T* ptr;

public:
    T* operator->() {
        return ptr;
    }

    // const version, returns a pointer-to-const instead of just a pointer to
    // enforce the idea of the logical constness of this object 
    const T* operator->() const {
        return ptr;
    }

    T& operator*() {
        return *ptr;
    }

    // const version, returns a const reference instead of just a reference
    // to enforce the idea of the logical constness of this object
    const T& operator*() const {
        return *ptr;
    }
};

Tenga en cuenta que, debido a una decisión de diseño del creador del idioma, no puede sobrecargar el . operador.

Además, podrías pensar que operator* sobrecargaría el multiplicación operador en lugar del operador de deserencia. Sin embargo, este no es el caso, porque el operador de multiplicación toma un solo argumento (mientras que el operador de deserencia no toma argumentos), y debido a esto, el compilador puede decir cuál es cuál.

Finalmente, tenga en cuenta que operator-> devuelve un puntero pero operator* Devuelve una referencia. Es fácil confundirlos accidentalmente.

Otros consejos

Sobrecargar el -> operador:

template <typename T> class MyClass
{
    T * p;
public:
    T       * operator->()       { return p; }  // #1
    T const * operator->() const { return p; }
};

Tenga en cuenta que ambas cosas Las sobrecargas no mutaron el objeto; No obstante, decidimos hacer que el número 1 no sea de conteo, de modo que legalemos la Constura del Objeto en el Pineo. Esto a veces se llama "propagación de la concentración profunda" o algo de este tipo. El lenguaje D lleva esto mucho más allá.

El operador de acceso de miembro se puede sobrecargar para devolver un puntero al objeto a acceder:

T * operator->() {return ptr;}
T const * operator->() const {return ptr;}

También es posible que desee que el operador de deferencia haga que se sienta aún más como un puntero; Esto devuelve una referencia en su lugar:

T & operator*() {return *ptr;}
T const & operator*() const {return *ptr;}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top