English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

C++ Explicación detallada y ejemplos de herencia

 C++La herencia puede ser de un solo nivel o múltiple, cada conexión de herencia puede ser public, protected, private, o virtual o non-Virtual. Luego, las opciones de cada función miembro pueden ser virtual o non-Virtual o pure virtual. Este artículo solo realiza algunas verificaciones de puntos clave.

  Herencia pública, por ejemplo:

1 class base
2 {...}
3 class derived:public base
4 {...}

  Si se escribe así, el compilador entenderá que el objeto de tipo derived también es de tipo base, pero el objeto de tipo base no es de tipo derived. Esto es muy importante. Entonces, los parámetros de forma de función de tipo base son aplicables a derived, pero no al revés. A continuación se muestra el código de verificación, una función con un parámetro de tipo base, al que se le pasa derived debe ejecutarse con éxito, por el contrario, una función con un parámetro de tipo derived

#include <iostream>
#include <stdio.h>
class base
{
  public:
  base()
  :baseName(""),baseData(0)
  {}
  base(std::string bn,int bd)
  :baseName(bn),baseData(bd)
  {}
  std::string getBaseName() const
  {
    return baseName;
  }
  int getBaseData()const
  {
    return baseData;
  }
  private:
    std::string baseName;
    int baseData;
};
class derived:public base
{
  public:
    derived():base(),derivedName("")
    {}
    derived(std::string bn,int bd,std::string dn)
    :base(bn,bd),derivedName(dn)
    {}
    std::string getDerivedName() const
    {
      return derivedName;
    }
  private:
    std::string derivedName;
};
void show(std::string& info,const base& b)
{
  info.append("Nombre es ");
  info.append(b.getBaseName());
  info.append(", baseData es ");
  char buffer[10];
  sprintf(buffer,"%d",b.getBaseData());
    info.append(buffer);
}
int main(int argc, char* argv[])
{
  base b("test",10);
  std::string s;
  mostrar(s,b);
  std::cout<<s<<std::endl;
  derivada d("btest",5,"dtest");
  std::string ss;
  mostrar(ss,d);
  std::cout<<ss<<std::endl;
  return 0;
}

El resultado de la ejecución es:

base:baseName es test, baseData es 10
base:baseName es btest, baseData es 5

Cambiar el código, cambiando los parámetros de la función a derivada

void mostrar2(std::string& info,const derivada& d)
{
  info.append("Nombre es ");
  info.append(d.getBaseName());
  info.append(", baseData es ");
  char buffer[10];
  sprintf(buffer,"%d",d.getBaseData());
  info.append(buffer);
}

Llamar a show(ss, d); el compilador muestra un error

1 derived_class.cpp: En la función `int main(int, char**)':
2 derived_class.cpp:84: error: inicialización inválida de referencia de tipo 'const derivada&' desde expresión de tipo 'base'
3 derived_class.cpp:70: error: al pasar el argumento 2 de `void mostrar2(std::string&, const derivada&)

El segundo punto verifica various formas de herencia, primero se presenta una tabla

Modo de herencia\Tipo de miembro public protected private
public public protected No se puede heredar
protected protected protected No se puede heredar
private private private No se puede heredar

Aquí se explica, aquí solo se expresa el miembro de la clase base, heredado de los modos public, protected y private, después de lo cual, en la clase base original, los miembros public, protected y private se convierten en el tipo contenido en la tabla en la clase heredada

class base
{
  public:
    std::string testPublic()
    {
      return std::string("this is public base");
    }
  protected:
    std::string testProtected()
    {
      return std::string("this is protected base");
    }
  private:
    std::string testPrivate()
    {
      return std::string("this is private base");
    }
};
class derivedPublic:public base
{
  public:
    std::string testPubPublic()
    {
      return testPublic()+= "in derived";
    }
    std::string testProPublic()
    {  
      return testProtected()+= "in derived";
    }
    std::string testPriPublic()          
    {  
      return testPrivate()+= "in derived";
    }
};
int main(int argc, char* argv[])
{
  derivedPublic dpub;
  std::cout << dpub.testPublic() << std::endl; 
}

Report the following error, indicating that testPrivate() is not a derived private function but a base private function

derived11.cpp:16: error: `std::string base::testPrivate()' is private
derived11.cpp:36: error: within this context

This verifies that private type members cannot be inherited (public, private, protected). Note: private and protected are omitted from the proof.

It only needs to be verified that testProtected can be inherited by the third-level derived class but cannot be called directly by the third-level class, which means that after public inheritance, the inheritance type is protected, and if the base class is of Public type, the member can be inherited and can be called directly.

#include <iostream>
#include <string>
class base
{
  public:
    std::string testPublic()
    {
      return std::string("this is public base");
    }
  protected:
    std::string testProtected()
    {
      return std::string("this is protected base");
    }
  private:
    std::string testPrivate()
    {
      return std::string("this is private base");
    }
};
class derivedPublic:public base
{
  public:
    std::string testPubPublic()
    {
      return testPublic()+= "in derived";
    }
    std::string testProPublic()
    {  
      return testProtected()+= "in derived";
    }
//    std::string testPriPublic()          
//    {  
//      return testPrivate()+= "in derived";
//    }
};
class deepDerived:public derivedPublic
{
  public:
    std::string deepProtected()
    {
      return testProtected() +="in deep";
    }
    std::string deepPublic()
    {
      return testPublic() +="indeep";
    }
};
int main(int argc, char* argv[])
{
  derivedPublic dpub;
  std::cout << dpub.testProtected() << std::endl; 
  deepDerived deepdpub;
  std::cout << deepdpub.testPublic() << std::endl;
  std::cout << deepdpub.testProtected() << std::endl;
  std::cout << deepdpub.deepProtected() << std::endl;
  std::cout << deepdpub.deepPublic() << std::endl;
}

Here the server reports an error

derived12.cpp:13: error: `std::string base::testProtected()' is protected
derived12.cpp:62: error: within this context

This verifies that one is public and the other is protected. Protected cannot be called directly, but it can be called by public members after inheritance.
The following has been proven, the detailed steps are omitted. If you are interested in this part of the verification, you can see the code below.

#include <iostream>
#include <string>
class base
{
  public:
    std::string testPublic()
    {
      return std::string("this is public base");
    }
  protected:
    std::string testProtected()
    {
      return std::string("this is protected base");
    }
  private:
    std::string testPrivate()
    {
      return std::string("this is private base");
    }
};
class derivedPublic:public base
{
  public:
    std::string testPubPublic()
    {
      return testPublic()+= "in derived";
    }
    std::string testProPublic()
    {  
      return testProtected()+= "in derived";
    }
//    std::string testPriPublic()          //Los miembros privados no se han heredado
//    {  
//      return testPrivate()+= "in derived";
//    }
};
class deepDerived:public derivedPublic
{
  public:
    std::string test()
    {
      return testPublic() +="in 3";
    }
};
class derivedProtected:protected base
{
  public:
    std::string testPubProtected()
    {
      return testPublic()+= "in derived";
    }
    std::string testProProtected()
    {  
      return testProtected()+= "in derived";
    }
};
class deepDerived2:public derivedProtected
{
  public:
    std::string test()
    {
      return testPublic() +="in 3";
    }
};
class derivedPrivate:private base
{
  public:
    std::string testPubPirvate()
    {
      return testPublic()+= "in derived";
    }
    std::string testProPrivate()
    {  
      return testProtected()+= "in derived";
    }
};
//class deepDerived3:public derivedPrivate
//{
//  public:
//    std::string test()
//    {
//      return testPublic() +="in 3";
//    }
//};
int main(int argc, char* argv[])
{
  derivedPublic dpub;
  //derivedProtected dpro;
  //derivedPrivate dpri;
  std::cout << dpub.testPublic() << std::endl;    //
  //std::cout << dpub.testProtected() << std::endl;  //El usuario heredado también no se puede usar
  //cout << dpub.testPrivate() << std::endl;     //las clases base son funciones privadas
  std::cout << dpub.testPubPublic() << std::endl;
  std::cout << dpub.testProPublic() << std::endl;
  //std::cout << dpub.testPriPrivate() << std::endl; //no se ha heredado
  deepDerived dd;
  std::cout << dd.test() << std::endl;
  derivedProtected dpro;
  //std::cout << dpro.testPublic() << std::endl;    //convertirse en tipo protected
  std::cout << dpro.testPubProtected() << std::endl;
  std::cout << dpro.testProProtected() << std::endl;
  deepDerived2 dd2;
  std::cout << dd2.test() << std::endl;
  derivedPrivate dpri;
  std::cout << dpri.testPubPirvate() << std::endl;
  std::cout << dpri.testProPrivate() << std::endl;
//  deepDerived3 dd3;
//  std::cout << dd3.test() << std::endl;
}

Aquí está el C++ Recopilación de materiales heredados de j, continuará complementando información relevante, gracias a todos por el apoyo a este sitio!

Declaración: el contenido de este artículo se obtiene de la red, es propiedad del autor original, el contenido se contribuye y carga de manera autónoma por los usuarios de Internet, este sitio no posee los derechos de propiedad, no se ha realizado una edición humana y no asume ninguna responsabilidad legal. Si encuentra contenido sospechoso de infracción de derechos de autor, por favor envíe un correo electrónico a: notice#oldtoolbag.com (al enviar un correo electrónico, reemplace # con @ para denunciar y proporcione evidencia. Una vez confirmado, este sitio eliminará inmediatamente el contenido sospechoso de infracción de derechos de autor.)

Te gustará