2011-04-15 18 views
8

¿Debo necesitar redefinir todos los operadores de sobrecarga con tipo derivado si necesito usarlos en la clase derivada?Operadores de sobrecarga en la clase derivada

El siguiente código compila bien:

class Point { 

public: 

    Point(int X = 0, int Y = 0):x(X), y(Y) {} 

    virtual ~Point() {} 

    Point operator +(Point &rhs) { 
     return Point(x + rhs.x, y + rhs.y); 
    } 

protected: 
    int x, y; 
}; 

class Vector : public Point { 

public: 

    Vector(int X, int Y) : Point(X, Y) {} 

    ~Vector() {} 

    Vector operator +(Vector &rhs) { 
     return Vector(x + rhs.x, y + rhs.y); 
    } 
}; 

int main() 
{ 
    Vector v1(1, 2); 
    Vector v2(3, 2); 

    Vector v3 = v2 + v1; 
} 

Pero por lo que he leído,

cuarto C++ Primer Ed. Sección 15.5.3.

Si una clase derivada quiere hacer todas las versiones sobrecargadas disponibles a través de su tipo, entonces debe, o bien redefinen todos ellos o ninguno de ellos.

¿La parte de la frase "none of them" tiene sentido aquí?

Respuesta

6

Lo que significa es que si Point tenía más de un operator+(), y usted solo redefinió uno de ellos, entonces solo ese sería accesible en la clase derivada; las otras sobrecargas estarían ocultas. Si declara nooperator+() en la clase derivada, entonces todos los padres están disponibles; si declara cualquier en la clase derivada, entonces ninguno de los padres están disponibles.

¿Tiene sentido? Este caso está bien: el padre declara uno, y usted redefine ese. No hay problemas. Si el padre declaró dos, entonces, su clase secundaria, que solo declara uno, solo tendría acceso a esa.

+3

@Ernest Friedman-Hill: 1. 'Override' es aplicable solo para funciones virtuales. Este caso es 'overloading' 2. Los miembros son heredados pero' hidden' debido a la sobrecarga de clase derivada. –

+0

Sí, esto es todo correcto. Mi lenguaje es bastante impreciso y más bien de color Java; Lo retocaré. –

+0

@ Ernest Friedman-Hill: Disculpas, ya había publicado una respuesta antes de formatearla o me habría abstenido. –

5

Overloading operators in derived class from IBM.

una función miembro llamada f en una clase A ocultará todos los otros miembros nombrados f en las clases de base de A, independientemente de tipos de retorno o argumentos. El siguiente ejemplo demuestra esto:

struct A { 
    void f() { } 
}; 

struct B : A { 
    void f(int) { } 
}; 

int main() { 
    B obj_B; 
    obj_B.f(3); 
// obj_B.f(); 
} 

El compilador no permitirían que la llamada obj_B.f función(), ya que la declaración de vacío B :: f (int) ha ocultado A: :F().

a la sobrecarga, en lugar de esconderse, una función de una clase base A en un clase B derivada, introducir el nombre de la función en el ámbito de B con una declaración using. El siguiente ejemplo es el mismo que el ejemplo anterior excepto por el uso de declaración usando A :: f:

struct A { 
    void f() { } 
}; 

struct B : A { 
    using A::f; 
    void f(int) { } 
}; 

int main() { 
    B obj_B; 
    obj_B.f(3); 
    obj_B.f(); 
} 

Así que si no sobrecargar todos ellos, a continuación, sólo las funciones sobrecargadas serán usado.

+1

Oye, ¿crees que está bien citar este contenido de otra persona? Me parece un problema de derechos de autor. –

+0

@Ernest: No creé el lenguaje C++, así que tendré que hacer referencia a algo. Ver esta meta pregunta similar: http://meta.stackexchange.com/questions/46448/answers-with-external-references-should-they-not-be-added-to-answers-and-perhap –

+0

+1 para el solución correcta Podrías haber hecho esta publicación mucho más corta, ya que vinculaste al contenido original. –

2

En C++, no hay sobrecarga en todos los ámbitos Los ámbitos de clase derivados no son una excepción a esta regla general.

No hay resolución de sobrecarga entre la clase derivada y la clase base. Un ejemplo:

class B 
{ 
    public: 
    int func1(int i) 
    { 
     cout<<"B::func1()"; 
     return i+1; 
    } 
}; 



class D : public B 
{ 
    public: 
    double func1(double d) 
    { 
     cout<<"D::func1()"; 
     return d+1.3; 
    } 
}; 

int main() 
{ 
    D *pd = new D; 

    cout << pd->func1(2) <<endl; 
    cout << pd->func1(2.3)<<endl; 

    return 0; 
} 

La salida es:

D::func1()3.3 
D::func1()3.6 

Esta misma regla se aplica para funciones miembro operador así, después de todo son funciones miembro también!

Así que en su ejemplo de código si Point tenido más de un operator+(), y se redefinió el mismo operador en la clase derivada entonces sólo ese operador clase derivada se podrá acceder a los objetos de la clase derivada, ya que la versión de la función hides la otra base versiones de clase de operator+().
Si no redefine el operator+() en la clase derivada, entonces ninguna de las versiones de clase primaria del operator+() está oculta y, por lo tanto, accesible a través de los objetos de la clase Derivada.

ahí la afirmación:
If a derived class wants to make all the overloaded versions available through its type, then it must either redefine all of them or none of them.

Además, tenga en cuenta que overloading, overriding y function hiding son tres términos que son vagamente mis-utilizados indistintamente veces pero todos ellos tienen significados distintos.

Cuestiones relacionadas