Ambigüedad de herencia en C++

Requisitos previos: herencia en C++ , herencia múltiple en C++

En las herencias múltiples, cuando una clase se deriva de dos o más clases base, puede existir la posibilidad de que las clases base tengan funciones con el mismo nombre, y la clase derivada puede no tener funciones con ese nombre como las de sus clases base. Si el objeto de la clase derivada necesita acceder a una de las funciones miembro de las clases base con nombres similares, se genera ambigüedad porque el compilador se confunde acerca de qué función miembro de la clase base debe llamarse. 

Ejemplo :

C++

// C++ program to show inheritance ambiguity
 
#include<iostream>
using namespace std;
 
// Base class A
 
class A {
    public:
 
    void func() {
        cout << " I am in class A" << endl;
    }
};
 
// Base class B
 
class B {
    public:
 
    void func() {
        cout << " I am in class B" << endl;
    }
};
 
// Derived class C
 
class C: public A, public B {
 
 
};
 
// Driver Code
 
int main() {
 
    // Created an object of class C
 
    C obj;
 
    // Calling function func()
 
    obj.func();
   
    return 0;
}

Salida :

prog.cpp: In function ‘int main()’:
prog.cpp:43:9: error: request for member ‘func’ is ambiguous
     obj.func();
         ^
prog.cpp:21:10: note: candidates are: void B::func()
     void func() {
          ^
prog.cpp:11:10: note:                 void A::func()
     void func() {
          ^

En este ejemplo, la clase derivada C heredó las dos clases base A y B que tienen el mismo nombre de función func(). Cuando se crea el objeto de la clase C y se llama a la función func(), el compilador se confunde sobre qué función func() miembro de la clase base debe llamarse.

Solución a la ambigüedad:

Para resolver esta ambigüedad , se utiliza el operador de resolución de alcance denotado por ‘ ::

Sintaxis:

ObjectName.ClassName::FunctionName();

A continuación se muestra el programa para mostrar el concepto de resolución de ambigüedad en herencias múltiples.

C++

// C++ program to resolve inheritance
// ambiguity
 
#include<iostream>
using namespace std;
 
// Base class A
 
class A {
    public:
 
    void func() {
        cout << " I am in class A" << endl;
    }
};
 
// Base class B
 
class B {
    public:
 
    void func() {
        cout << " I am in class B" << endl;
    }
};
 
// Derived class C
class C: public A, public B {
 
 
};
 
// Driver Code
 
int main() {
 
    // Created an object of class C
    C obj;
 
    // Calling function func() in class A
    obj.A::func();
 
    // Calling function func() in class B
    obj.B::func();
 
    return 0;
}
Producción

 I am in class A
 I am in class B

Fragmento de código :

  • Hemos creado una clase «A» que consta de la función miembro pública «func».
  • Hemos creado una clase «B» que también consta de la función miembro pública «func».
  • Hemos creado una clase «C» que hereda las clases «A» y «B».
  • Se crea el objeto “obj” de la clase derivada “C”.
  • La función “func” es llamada por el objeto “obj”.

Lo importante a tener en cuenta aquí es que cuando la función «func» es llamada por el objeto «obj» por primera vez, invocará la función «func» de la clase «A» y cuando la función «func» es llamada por el objeto “obj” por segunda vez invocará la función “func” de la clase “B” porque la habíamos especificado usando el operador de resolución de alcance “::” para eliminar la ambigüedad.

Anulación de función o anulación de método

C++

// C++ program to show function/method overriding
 
#include<iostream>
using namespace std;
 
// Base class A
 
class A {
    public:
 
    void func() {
        cout << " I am in class A" << endl;
    }
};
 
// Base class B
class B {
    public:
 
    void func() {
        cout << " I am in class B" << endl;
    }
};
 
// Derived class C
class C: public A, public B {
    public:
   
    // Function overriding
    void func() {
        cout << " I am in class C" << endl;
    }
};
 
// Driver Code
 
int main() {
 
    // Created an object of class C
    C obj;
 
    // Calling function func() in class C
    // through scope resolution operator
    obj.C::func();
 
    // Calling function func() in class C
    // by default by compiler because of
    // method or function overriding
    obj.func();
 
    return 0;
}
Producción

 I am in class C
 I am in class C

En este ejemplo, podemos ver que también hemos declarado la función func() en la clase derivada «C». Por lo tanto, cuando se crea un objeto de clase «C» y se llama a la función func(), se imprime «Estoy en la clase C» porque anulará el método «func» de la clase base debido a la anulación de función/método. Ahora, si no especificamos a qué función miembro de clase «func» se debe llamar a través del operador de resolución de alcance, el compilador ejecuta de manera predeterminada el método que está escrito en el cuerpo de la clase a través de la cual se crea la instancia del objeto. Pero si la función «func» no estaba presente en la clase derivada «C», entonces para llamar a la función «func» en la clase «A» o «B», debemos especificarla a través del operador de resolución de alcance. Entonces, el compilador ejecutará el método de la clase especificada.

Publicación traducida automáticamente

Artículo escrito por akashjha2671 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *