2009-01-22 9 views
25
class Test { 

     bool isVal() const { 
      return isVal; 
     } 

    private: 

     bool isVal; 
}; 

sobre la compilación de este archivo que dice¿Método de clase y variable con el mismo nombre, error de compilación en C++ no en Java?

testClass.cpp: 9: declaración de `bool Test :: isVal'

testClass.cpp: 3: conflictos con previa declaración` bool Test :: isVal()'

pesar de que la misma funcione para java

class Test { 

    private boolean isVal; 

    public boolean isVal() { 
     return isVal; 
    } 

} 

No estoy seguro de por qué C++ no puede manejar esto.

+10

No "no puedo"; "elige no". El tono acusatorio no es apropiado. –

Respuesta

53

Porque C++ no es Java. Usted puede tomar la dirección de un miembro de:

&Test::isVal 

lo que no puede tener dos miembros tienen el mismo nombre, excepto que se puede sobrecargar las funciones miembro. Incluso si pudieras eliminar la ambigüedad por algún tipo de yeso, el siguiente problema ya surgiría en otros lugares.

En C++, mucha gente, incluyéndome a mí, generalmente llama a los miembros de datos especialmente, como poner un m antes de su nombre. Esto evita el problema:

class Test { 
public: 
    bool IsVal() const { return mIsVal; } 
private: 
    bool mIsVal; 
}; 
+1

... y, bajo las sábanas, las funciones realmente no tienen el mismo nombre de todos modos, ya que se distinguen por clase y firma de argumento. –

+18

En C++, generalmente llamamos variables de miembro especialmente, como poner una m antes de su nombre ???? ¿Hacemos? ¿Está eso en la especificación del idioma? Esta es una respuesta perfecta hasta esa frase y el ejemplo que la sigue. – jmucchiello

+7

joe_mucchiello, salir y contar todo el popular nombre mangling, como "data_", "_data", "mData", "m_data", etc .... Creo que justifica mi uso de "generalmente". –

5

Funciones en C/C++ son sólo punteros a una ubicación en la memoria donde se encuentra el código, isVal (como un booleano) y isVal (como una función) son por lo tanto ambiguo.

3

La respuesta rápida es "porque esa es la forma en que C++ funciona". C++ no tiene un espacio de nombre separado para las variables miembro y las funciones miembro (es decir, "métodos") donde Java (aparentemente, como no lo he probado) lo hace.

En cualquier caso, recuerde la vieja historia sobre el tipo que fue a un médico y le dijo "Doc, me duele cuando hago este". A lo que el médico respondió "bueno, no haga eso!" Esta es una peculiaridad del lenguaje en su camino para convertirse en un truco de programador tonto.

-1

Si tiene alguna razón para utilizar los mismos nombres de variable y método (tal vez reducir la nomenclatura para las cosas tienen casi el mismo propósito, etc ??), sugiero que sólo les nomenclatura en los diferentes casos:

class Test 
{ 
    private bool isVal; 
    public bool ISVAL() 
    { return isVal; } 
} 
+4

Yo no. Mayúsculas para funciones miembro? Ew. –

8

C++ aplica el nombre que cambia a nombres de funciones y variables globales. Las variables locales no se destrozan. El problema surge porque en C puede acceder a la dirección de una variable o función (también en C++), p. :

struct noob{ 
    bool noobvar; 
    void noobvar(){}; 
}; 

Se puede decir, por qué no aplicar el nombre mangling a las variables locales, así y luego tener una representación local interno como

bool __noobvar_avar; 
void __noobvar_void_fun; 

y supongamos que reciben las direcciones durante 0x000A ejecución y 0x00C0 respectivamente.

Sin embargo, si se escribe en alguna parte del código:

&noob::noobvar 

Qué debe hacer el programa?

  1. devolver la dirección de la noobvar variable, es decir 0x000A
  2. regreso de los Addres de la función noobvar, es decir 0x00C0

Se puede ver que, dado que en C, y por lo tanto en C++, puede emite una "dirección de", no es legal tener variables y funciones con el mismo nombre dentro del mismo alcance de resolución.

2

La siguiente sección del C++ Draft Standard N3337 especifica cuándo se puede sobrecargar un nombre.

13 sobrecargar

1 Cuando dos o más diferentes declaraciones se especifican para un único nombre en el mismo ámbito, se dice que el nombre a ser sobrecargado. Por extensión, dos declaraciones en el mismo ámbito que declaran el mismo nombre pero con diferentes tipos se llaman declaraciones sobrecargadas. Solo las declaraciones de plantilla de función y función pueden sobrecargarse; las declaraciones de variables y tipos no se pueden sobrecargar.

Al definir una clase como:

class Test { 

     bool isVal() const { 
      return isVal; 
     } 

    private: 

     bool isVal; 
}; 

que estén sobrecargando el nombre isVal dentro del ámbito de la clase. Tal sobrecarga solo está permitida cuando isVal es una función miembro. No está permitido cuando isVal es una variable miembro.

Cuestiones relacionadas