2009-02-06 16 views
67

Sería muy útil poder sobrecargar el. operador en C++ y devolver una referencia a un objeto.¿Por qué no puedes sobrecargar el '.' operador en C++?

Puede sobrecarga operator-> y operator* pero no operator.

¿Existe una razón técnica para esto?

+4

Puede dar un ejemplo de cuándo desea anular el '.' ¿operador? –

+4

Generalmente, el caso de uso es "referencias inteligentes". Una especie de Proxy. – ddaa

+2

@Gamecat: lea [esto] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1671.pdf) propuesta para agregar la capacidad de sobrecargar el 'operador' y 'operator. *', tiene algunos ejemplos. – Mankarse

Respuesta

51

Ver this quote from Bjarne Stroustrup:

operador. (punto) podría en principio estar sobrecargado usando la misma técnica que se usa para ->. Sin embargo, si lo hace, puede generar preguntas sobre si una operación está destinada a la sobrecarga del objeto. o un objeto al que hace referencia. Por ejemplo:

class Y { 
public: 
    void f(); 
    // ... 
}; 

class X { // assume that you can overload . 
    Y* p; 
    Y& operator.() { return *p; } 
    void f(); 
    // ... 
}; 

void g(X& x) 
{ 
    x.f(); // X::f or Y::f or error? 
} 

Este problema se puede resolver de varias maneras. En el momento de la estandarización , no era obvio cuál sería el mejor. Para obtener más detalles sobre , consulte The Design and Evolution of C++.

+0

cita completa de TDaEoC++ en mi respuesta. – ddaa

+12

Estoy tentado de votar esto por plagio/recolocación. Al citar, citar textualmente, no modificar. Y usa los formatos de cotización. –

+0

muy buen ejemplo y explicación. – Manju

27

BS has an answer for this question:

operador. (punto) podría en principio ser sobrecargado usando la misma técnica que usada para ->. Sin embargo, al hacerlo, puede llevar a preguntas sobre si una operación está destinada para el objeto sobrecarga. o un objeto referido a por. Por ejemplo:

class Y { 
public: 
    void f(); 
    // ... 
}; 
class X { // assume that you can overload . 
    Y* p; 
    Y& operator.() { return *p; } 
    void f(); 
    // ... 
}; 
void g(X& x) 
{ 
    x.f(); // X::f or Y::f or error? 
} 

Este problema se puede resolver de varias maneras . En el momento de la estandarización, , no era obvio cuál sería el mejor . Para más detalles, vea D&E.

+0

Ver mi comentario sobre la respuesta de Anton – slashmais

47

Stroustrup dijo que C++ debe ser un lenguaje extensible, pero no mutable.

El operador de punto (acceso de atributo) se veía demasiado cerca del núcleo del lenguaje como para permitir la sobrecarga.

Ver The Design and Evolution of C++, página 242, sección 11.5.2 Smart References.

Cuando decidí permitir que la sobrecarga del operador ->, yo, naturalmente, si consideraba operador . podría estar sobrecargado de manera similar.

En ese momento, consideré los siguientes argumentos concluyentes: Si obj es un objeto de clase, entonces obj.m tiene un significado para cada miembro m de la clase de ese objeto. Tratamos de no hacer que el lenguaje sea mutable redefiniendo las operaciones integradas (aunque esa regla se infringe para = fuera de la necesidad extrema, y ​​para el & único).

Si permitimos que la sobrecarga de . para una clase X, no podríamos acceder a los miembros de X por medios normales; tendríamos que usar un puntero y ->, pero -> y & también podrían haber sido redefinidos. Yo quería un lenguaje extensible, no mudable.

Estos argumentos son importantes, pero no concluyentes. En particular, en 1990, Jim Adcock propuso permitir la sobrecarga del operador .exactamente de la misma forma que el operador ->.

El "I" en esta cita es Bjarne Stroustrup. No puedes ser más autoritario que eso.

Si realmente quiere entender C++ (como en "por qué es así"), debería leer este libro en su totalidad.

1

Es muy fácil de entender, si va a través del mecanismo interno de invocación de la función del operador, Digamos que un complejo de clases puede tener dos miembros r para la parte real y yo para la parte imaginaria. Diga Complejo C1 (10,20), C2 (10,2) // suponemos que ya hay un constructor de dos argumentos dentro de la clase. Ahora, si escribe C1 + C2 como una declaración, el compilador intentará encontrar la versión sobrecargada del operador + en el número complejo. Ahora suponemos que sobrecarga el operador +, así que C1 + C2 traducido internamente como c1.operator + (c2) Supongamos por ahora que los seres pueden sobrecargar '.' operador. por lo que ahora piensan siguiente llamada C1.disp() // mostrar el contenido de un objeto complejo Ahora intenta representar como una representación interna C1.operator. (------), cosas completamente desordenado creados. Esa es la razón por la cual no podemos sobrecargar '.' operador

+1

Algunas personas dicen que la traducción interna no debe llamar al 'operador' sobrecargado. – curiousguy

Cuestiones relacionadas