2011-08-31 14 views
5

en "The C++ lenguaje de programación", en la página 265, el autor hace la siguiente declaración:Pregunta sobre significados predefinidos para los operadores

A causa de un accidente histórico, la operadores = (asignación), & (Dirección- de), y (secuencia: §6.2.2) tienen significados predefinidos cuando se aplican a objetos de clase. Estos significados predefinidos pueden hacerse inaccesible para los usuarios en general, haciéndolos privada:

A continuación, se da el siguiente ejemplo:

class X { 
private: 
void operator=(const X&); 
void operator&(); 
void operator,(const X&); 
// ... 
}; 

void f(X a, X b) 
{ 
    a = b; // error: operator= private 
    &a;  // error: operator& private 
    a,b; // error: operator, private 
} 

No acabo de entender lo qué se refieren estos comentarios de "error" ¿a? ¿Significa eso que no debería definir una función como f, o que todos los operadores =, & y , deberían utilizarse de la manera predeterminada, y no es necesario redefinirlos?

Respuesta

8

Este ejemplo simplemente muestra una manera de evitar que usted u otros desarrolladores del código utilicen operadores, que pueden usarse sin haberse definido en la clase, porque se generan automáticamente (y tienen significados por defecto para las operaciones que representar).

El autor del ejemplo quería decir, que si se intenta asignar a ba (en línea a = b) que hará que un error, debido a que el operador de asignación es privado en la definición de clase.

Se produce un error similar en el caso de la dirección de entrada en la segunda línea y el operador de coma en la tercera.

Convertir operadores/constructores predeterminados en privados si sabes que no se deben usar (o no se han implementado aún) es bueno, porque uno puede usar accidentalmente un operador muy frecuente como asignación o copia-constructor, siendo sin saber que su comportamiento predeterminado entra en conflicto con el ciclo de vida de la clase. Si dicho operador o constructor se hace privado al comienzo del diseño de la clase, el compilador generará un error en tiempo de compilación en lugar de realizar una operación potencialmente peligrosa sin previo aviso si el programador usa accidentalmente el método.

Operador de asignaciones predeterminadas y puntero de miembro: copiará el puntero mientras que usted podría querer que el objeto sea el propietario de los datos. Luego, después de que alguien asigna un objeto a otro sin saber que la asignación no está implementada, terminará con un doble error libre. En lugar de eso, si el operador es privado, obtendrá un buen error y el código ni siquiera se compilará, y sabrá lo que está sucediendo.

1

Proporcionar su propia implementación de cualquier operador es básicamente lo mismo que implementar un método de clase. Los operadores y los métodos son los mismos en términos de accesibilidad. Lo que hace es rechazar el acceso a los operadores del código de la persona que llama.

Es exactamente lo mismo que si definieras un método privado y luego intentaras llamarlo desde algún código que no sea parte de tu clase. Simplemente haz públicos a los operadores y los errores desaparecerán.

1

Básicamente evita que cualquiera haga un objeto 'X' y utilizando los operadores "=", "&" y "," en esa clase. Debido a que el autor de la clase puede implementar esos objetos con un significado que es bastante diferente de lo que el consumidor de la clase podría pensar que hacen ... por lo que es mejor evitar que se utilicen en absoluto en el caso de ambigüedad.

1

La función f es un ejemplo de un usuario que intenta utilizar los operadores privados. Le muestra qué código está impidiendo al hacerlos privados. El comentario // error significa que un programa que contenía esa línea no compilaría por el motivo indicado.

5

El autor tiene la intención de señalar aquí que los operadores =, & y , suelen estar implícitamente disponibles para una clase.
Por lo tanto, si no desea que sus objetos sean operados a través de ellos, entonces los declara como private, impidiendo su uso.

Dado que están declarados como private ya no puede acceder a ellos fuera de la clase y el compilador le da un error de compilación. La función es un ejemplo que muestra eso.

+0

Encuentro esta respuesta más clara que la más votada: el punto de los * significados predefinidos * es que están presentes y funcionarán * de manera predeterminada *, y que la única forma de * inhibir * ese comportamiento en C++ 03 es declarándolos 'privados' (C++ 0x agrega la palabra clave' delete') –

0

Antes de hablar del error, una clave aquí es comprender que estas operaciones estarán implícitamente disponibles para su clase. Esta es la esencia del consejo de Scott Meyers "Saber qué funciones C++ escribe y llama silenciosamente".

C++ implementará automáticamente el operador de asignación para su clase, pero puede que no se realice correctamente (por ejemplo, si su clase contiene una variable de miembro de puntero). Al definir explícitamente el operador de asignación, le está diciendo al compilador que use su implementación en lugar de generar una para usted. Y al hacerlo privado, esencialmente no se permite la asignación de una instancia de clase a otra. En cualquier lugar que intente hacer esto en su código, el compilador se quejará, lo cual es bueno si realmente no desea que se realice la tarea.

En la función f, el autor le muestra que estas declaraciones no se compilarán debido a cómo se definen los operadores en la clase. Es perfectamente aceptable redefinir operadores para su clase y, a veces, definitivamente se requiere (por ejemplo, para implementar una copia profunda de una variable de miembro de puntero en su clase). El objetivo del ejemplo es mostrar que a) usted puede proporcionar su propia implementación de estos operadores para su clase, yb) debido a esto, usted tiene control sobre si los operadores son compatibles e implementados correctamente para su clase.