Función virtual

En programación orientada a objetos (POO), una función virtual o método virtual es una función cuyo comportamiento, al ser declarado "virtual", es determinado por la definición de una función con la misma cabecera en alguna de sus subclases. Este concepto es una parte muy importante del polimorfismo en la POO.

El concepto de función virtual soluciona los siguientes problemas:

En POO, cuando una clase derivada hereda de una clase base, un objeto de la clase derivada puede ser referido (o coercionado) tanto como del tipo de la clase base como del tipo de la clase derivada. Si hay funciones de la clase base redefinidas por la clase derivada, aparece un problema cuando un objeto derivado ha sido coercionado como del tipo de la clase base. Cuando un objeto derivado es referido como del tipo de la base, el comportamiento de la llamada a la función deseado es ambiguo.

Distinguir entre virtual y no virtual sirve para resolver este problema. Si la función en cuestión es designada "virtual", se llamará a la función de la clase derivada (si existe). Si no es virtual, se llamará a la función de la clase base.

Ejemplo

Por ejemplo, una clase base Animal podría tener una función virtual come. La subclase Pez implementaría come() de forma diferente que la subclase Lobo, pero se podría invocar a come() en cualquier instancia de una clase referida como Animal, y obtener el comportamiento de come() de la subclase específica.

Esto permitiría a un programador procesar una lista de objetos de la clase Animal, diciendo a cada uno que coma (llamando a come()), sin saber qué tipo de animales hay en la lista. Tampoco tendría que saber cómo come cada animal, o cuántos tipos de animales puede llegar a existir.

El siguiente, es un ejemplo en C++:

# include <iostream>
class Animal
{
public:
    virtual void come() { std::cout << "Yo como como un animal genérico.\n"; }
    virtual ~Animal() {}
};
 
class Lobo : public Animal
{
public:
    void come() { std::cout << "¡Yo como como un lobo!\n"; }
    virtual ~Lobo() {}
};
 
class Pez : public Animal
{
public:
    void come() { std::cout << "¡Yo como como un pez!\n"; }
    virtual ~Pez() {}
};
 
class OtroAnimal : public Animal
{
    virtual ~OtroAnimal() {}
};
 
int main()
{
    Animal *unAnimal[4];
    unAnimal[0] = new Animal();
    unAnimal[1] = new Lobo();
    unAnimal[2] = new Pez();
    unAnimal[3] = new OtroAnimal();
 
    for(int i = 0; i < 4; i++) {
        unAnimal[i]->come();
    }
    
    for (int i = 0; i < 4; i++) {
        delete unAnimal[i];
    }
    return 0;
}

Salida con el método virtual come:

Yo como como un animal genérico.
¡Yo como como un lobo!
¡Yo como como un pez!
Yo como como un animal genérico.

Salida sin el método virtual come:

Yo como como un animal genérico.
Yo como como un animal genérico.
Yo como como un animal genérico.
Yo como como un animal genérico.

Las Clases abstractas y funciones virtuales puras

Una función virtual pura o método virtual puro es una función virtual que necesita ser implementada por una clase derivada que no sea abstracta. Las clases que contienen métodos virtuales puros son denominadas "abstractas". Estas no pueden ser instanciadas directamente, y una subclase de una clase abstracta sólo puede ser instanciada directamente si todos los métodos virtuales puros han sido implementados por esa clase o una clase padre.

Los métodos virtuales puros normalmente tienen una declaración (cabecera) pero no tienen definición (implementación). Como ejemplo, una clase base abstracta como "SimboloMatematico" puede ofrecer una función virtual pura como hazOperacion, y las clases derivadas "Suma" y "Resta" pueden implementar hazOperacion para ofrecer implementaciones concretas. La implementación de hazOperacion no tendría sentido en la clase "SimboloMatematico" porque "SimboloMatematico" es un concepto abstracto cuyo comportamiento es definido solamente por cada tipo (subclase) de "SimboloMatematico" dado.

De forma similar, una subclase dada de "SimboloMatematico" no sería completa sin una implementación de hazOperacion. Aunque los métodos virtuales puros normalmente no tienen implementación en la clase que los declara, en C++ permite hacer esto, ofreciendo un comportamiento por omisión en el que la clase derivada puede delegar si es apropiado.

Las funciones virtuales puras también son utilizadas donde las declaraciones de métodos se utilizan para definir una interfaz para la que las clases derivadas proveerán todas las implementaciones. Una clase abstracta sirviendo como interfaz contiene sólo funciones virtuales puras, y ningún miembro de datos (variables, constantes, etc.) ni métodos ordinarios. El uso de clases puramente abstractas como interfaces funciona en C++ ya que este soporta herencia múltiple. Debido a que muchos lenguajes orientados a objetos no soportan herencia múltiple, normalmente ofrecen un mecanismo por separado para hacer interfaces. Esto es así por ejemplo en Java.

C++

En C++, las funciones virtuales puras son declaradas utilizando una sintaxis especial = 0 como se muestra a continuación:

 class B {
   virtual void una_funcion_virtual_pura() = 0;
 };

La declaración de la función virtual pura ofrece sólo la declaración del método. Normalmente no se ofrece una implementación de la función virtual pura en una clase abstracta, pero puede ofrecerse siempre que no sea en la declaración de la clase abstracta (no debe ser definida "inline"). Toda clase hija no-abstracta continúa necesitando redefinir el método, pero la implementación (definición) ofrecida por la clase abstracta puede ser llamada de esta forma:

void Abstracta::virtual_pura() {
  // haz algo
}

class Hija : Abstracta {
  virtual void virtual_pura(); // ya no es abstracta; puede ser instanciada
};

void Hija::virtual_pura() {
  Abstracta::virtual_pura(); // se ejecuta la implementación de la clase abstracta
}

El compilador sabe a qué implementación del método llamar en tiempo de ejecución creando una tabla de punteros a todas las funciones virtuales de una clase, llamada vtable o tabla virtual.

Destructores virtuales

Los lenguajes orientados a objetos normalmente gestionan la reserva y la liberación de memoria automáticamente cuando los objetos son creados y destruidos. Sin embargo, algunos lenguajes orientados a objetos permiten implementar un método destructor personalizado si se desea. Uno de estos lenguajes es C++, y como se ilustra en el siguiente ejemplo, es importante para una clase base de C++ tener un destructor virtual para asegurar que se llamará siempre al destructor de las clases derivadas inferiores. En el ejemplo siguiente, sin destructor virtual, al aplicarle el operador "delete" a una instancia de la clase B, se llamará correctamente al destructor de la clase B y al de la clase A si se elimina como instancia de B; una instancia de B, eliminada mediante un puntero a su clase base A, fallará al no llamar al destructor de B.

# include <iostream>

class A
{
public:
 
   A() { }
   ~A() { std::cout << "Destruye A" << std::endl; }
};
 
class B : public A
{
public:

  B() { }
  ~B() { std::cout << "Destruye B" << std::endl; }
};
 
int main()
{
  A* b1 = new B;
  B* b2 = new B;

  delete b1; // Sólo se llama a ~A() aunque b1 sea una instancia de la clase B
             // porque ~A() no se ha declarado como virtual
  delete b2; // Llama a los destructores ~B() y ~A()

  return 0;
}

Salida:

Destruye A
Destruye B
Destruye A

La declaración correcta del destructor para la clase A como virtual ~A() asegurará que el destructor para la clase B sea llamado en ambos casos del ejemplo anterior.

Véase también

Referencias

  • C++ FAQ Lite Copyright © 1991-2006, Marshall Cline. (en inglés)

Read other articles:

Arsitektur gaya Khmer. Arsitektur Khmer adalah konstruksi dari periode Angkor antara pertengahan abad ke-8 Masehi sampai pertengahan abad ke-15. Periodisasi Gaya Preah Ko (877-886 Masehi) Gaya Bakheng (889-923) Gaya Koh Ker (921-944) Gaya Pre Rup (944-968) Gaya Banteay Srei (967-1000) Gaya Khleang (968-1010) Gaya Baphuon (1050–1080) Gaya Angkor Wat atau Klasik (1080–1175) Gaya Baroque atau Bayon (1181–1243) Gaya pasca Bayon (1243–1431) Lihat juga Wikimedia Commons memiliki media menge...

 

Grand-Place, BrusselSitus Warisan Dunia UNESCOGrand-Place; Balai Kota Brussel terletak di sebelah kiri.KriteriaBudaya: ii, ivNomor identifikasi857Pengukuhan1998 (22) Grand-Place (bahasa Prancis, diucapkan [ɡʁɑ̃ plas]; juga digunakan dalam bahasa Inggris) atau Grote Markt (bahasa Belanda, pelafalan [ˌɣroːtə ˈmɑrkt] ⓘ) adalah alun-alun utama di kota Brussel. Alun-alun ini dikelilingi oleh balai-balai kongsi yang mewah dan dua bangunan yang lebih besar, Balai Kota B...

 

Artikel ini sudah memiliki referensi, tetapi tidak disertai kutipan yang cukup. Anda dapat membantu mengembangkan artikel ini dengan menambahkan lebih banyak kutipan pada teks artikel. (Maret 2019) (Pelajari cara dan kapan saatnya untuk menghapus pesan templat ini) Politeknik Negeri PontianakDidirikan1987DirekturDr. H. Widodo PS, ST., MTStaf akademik234 (2011)LokasiKota Pontianak, Kalimantan Barat, Indonesia Politeknik Negeri Pontianak atau biasa disingkat Polnep adalah sebuah perguruan tingg...

Si ce bandeau n'est plus pertinent, retirez-le. Cliquez ici pour en savoir plus. Cet article ne cite pas suffisamment ses sources (mars 2017). Si vous disposez d'ouvrages ou d'articles de référence ou si vous connaissez des sites web de qualité traitant du thème abordé ici, merci de compléter l'article en donnant les références utiles à sa vérifiabilité et en les liant à la section « Notes et références » En pratique : Quelles sources sont attendues ? Comme...

 

Engineering college in Kanhangad, Kasaragod District, Kerala, India North Malabar Institute of TechnologyEstablished2012Academic affiliationKannur UniversityLocationKanhangad, Kerala, India12°21′14″N 75°08′38″E / 12.3539°N 75.1438°E / 12.3539; 75.1438LanguageEnglishWebsitewww.nmitkerala.ac.in North Malabar Institute of Technology is an engineering college located at Kanhangad, Kasaragod district, Kerala, India. It is affiliated to Kannur University.[1&...

 

Darius II𐎭𐎠𐎼𐎹𐎺𐎢𐏁Darius II sebagaimana yang digambarkan pada makamnya di Naqsy-e RostamRaja Diraja IranBerkuasa423–404 SMPendahuluArtahsasta IPenerusArtahsasta IIPesaingXerxes II (424 SM)Sogdyana (424-423 SM)Firaun MesirBerkuasa423–404 SMPendahuluArtahsasta IPenerusAmenirdisuInformasi pribadiKematian404 SMWangsaAkhemeniyahAyahArtahsasta IIbuKosmartidene dari BabiloniaPasanganParysatisAnakArtahsasta IIKoresyUstana (Ostanes)AgamaZoroastrianisme Darius II (bahasa Persia K...

Untuk kegunaan lain, lihat Permutasi (disambiguasi). nPr beralih ke halaman ini. Untuk kegunaan lain, lihat NPR (disambiguasi). artikel ini perlu dirapikan agar memenuhi standar Wikipedia. Tidak ada alasan yang diberikan. Silakan kembangkan artikel ini semampu Anda. Merapikan artikel dapat dilakukan dengan wikifikasi atau membagi artikel ke paragraf-paragraf. Jika sudah dirapikan, silakan hapus templat ini. (Pelajari cara dan kapan saatnya untuk menghapus pesan templat ini) Artikel ini tidak ...

 

County in Pennsylvania, United States County in PennsylvaniaTioga CountyCountyTioga County CourthouseLocation within the U.S. state of PennsylvaniaPennsylvania's location within the U.S.Coordinates: 41°46′N 77°15′W / 41.77°N 77.25°W / 41.77; -77.25Country United StatesState PennsylvaniaFoundedOctober 13, 1812Named forTioga RiverSeatWellsboroLargest boroughMansfieldArea • Total1,137 sq mi (2,940 km2) • Land1,134&#...

 

French architect Auguste PerretPortrait of Auguste Perret (1932)Born(1874-02-12)12 February 1874Ixelles, BelgiumDied25 February 1954(1954-02-25) (aged 80)Paris, FranceNationalityFrenchOccupationArchitectAwardsAIA Gold Medal (1952)BuildingsThéâtre des Champs-ÉlyséesSt. Joseph's Church, Le HavreFrench Economic, Social and Environmental CouncilÉglise Notre-Dame du Raincy Auguste Perret (12 February 1874 – 25 February 1954) was a French architect and a pioneer of the architectural use...

Sceaux 行政国 フランス地域圏 (Région) イル=ド=フランス地域圏県 (département) オー=ド=セーヌ県郡 (arrondissement) アントニー郡小郡 (canton) 小郡庁所在地INSEEコード 92071郵便番号 92330市長(任期) フィリップ・ローラン(2008年-2014年)自治体間連合 (fr) メトロポール・デュ・グラン・パリ人口動態人口 19,679人(2007年)人口密度 5466人/km2住民の呼称 Scéens地理座標 北緯48度4...

 

Азиатский барсук Научная классификация Домен:ЭукариотыЦарство:ЖивотныеПодцарство:ЭуметазоиБез ранга:Двусторонне-симметричныеБез ранга:ВторичноротыеТип:ХордовыеПодтип:ПозвоночныеИнфратип:ЧелюстноротыеНадкласс:ЧетвероногиеКлада:АмниотыКлада:СинапсидыКласс:Мле�...

 

Ця стаття потребує додаткових посилань на джерела для поліпшення її перевірності. Будь ласка, допоможіть удосконалити цю статтю, додавши посилання на надійні (авторитетні) джерела. Зверніться на сторінку обговорення за поясненнями та допоможіть виправити недоліки. Мат...

 烏克蘭總理Прем'єр-міністр України烏克蘭國徽現任杰尼斯·什米加尔自2020年3月4日任命者烏克蘭總統任期總統任命首任維托爾德·福金设立1991年11月后继职位無网站www.kmu.gov.ua/control/en/(英文) 乌克兰 乌克兰政府与政治系列条目 宪法 政府 总统 弗拉基米尔·泽连斯基 總統辦公室 国家安全与国防事务委员会 总统代表(英语:Representatives of the President of Ukraine) 总...

 

A competitor in the 2004 Horse Trials shows good form over the first fence on the cross-country course. The Defender Burghley Horse Trials is an annual three-day event held at Burghley House near Stamford, Lincolnshire, England, currently in early September. Defender Burghley Horse Trials is classified by the FEI as one of the seven leading three-day events in the world (the others being the Badminton Horse Trials, the Kentucky Three-Day Event, the Australian International Three Day Event, t...

 

Journalism school at Columbia University This article has multiple issues. Please help improve it or discuss these issues on the talk page. (Learn how and when to remove these template messages) This article relies excessively on references to primary sources. Please improve this article by adding secondary or tertiary sources. Find sources: Columbia University Graduate School of Journalism – news · newspapers · books · scholar · JSTOR (June 2021) (Lea...

Malaysian businessman (born 1960) In this Malay name, there is no surname or family name. The name Meranun is a patronymic, and the person should be referred to by their given name, Kamarudin. The word bin or binti/binte means 'son of' or 'daughter of', respectively. Yang Berbahagia DatukKamarudin MeranunPJN DSAP DSPNBorn1960Miri, Crown Colony of Sarawak (now Malaysia)NationalityMalaysianEducationDiploma in Actuarial Science(Universiti Teknologi MARA)Occupation(s)CEOTune GroupChairmanAirAsiaC...

 

Oud

Pear-shaped stringed musical instrument For other uses, see Oud (disambiguation). OudOud crafted by Emmanuel Venious in 1916String instrumentOther namesArabic: عود, Persian: عودClassification String instruments Necked bowl lutes Hornbostel–Sachs classification321.321-6(Composite chordophone sounded with a plectrum)DevelopedIslamic Golden AgeRelated instruments List Angélique Archlute Barbat (lute) Baglamadaki Bağlama Bipa Biwa Bouzouki Çifteli Cobza Cümbüş Daguangxian Đàn tỳ...

 

Village in Qazvin province, Iran For other places with the same name, see Radekan. Village in Qazvin, IranRadekan Persian: رادكانVillageRadekanCoordinates: 35°59′21″N 49°34′44″E / 35.98917°N 49.57889°E / 35.98917; 49.57889[1]CountryIranProvinceQazvinCountyTakestanDistrictKhorramdashtRural DistrictRamand-e ShomaliPopulation (2016)[2] • Total2,306Time zoneUTC+3:30 (IRST) Radekan (Persian: رادكان)[a] is a vi...

Untuk kapal lain dengan nama serupa, lihat Kapal Jepang Kashima. JDS Kashima di Pearl Harbour selama April 2008 Sejarah Jepang Dipesan 1992Pembangun Hitachi Zosen CorporationPasang lunas 20 April 1993Diluncurkan 23 Februari 1994Mulai berlayar 26 Januari 1995Pelabuhan daftar KureIdentifikasiNomor MMSI: 431999529Status Aktif Ciri-ciri umum Kelas dan jenis Kapal Latih kelas KashimaBerat benaman 4,050 tons Standard displacementPanjang 143 m (469 ft)Lebar 18 m (59 ft)Sarat air ...

 

Aretha FranklinFranklin pada tahun 1968LahirAretha Louise Franklin(1942-03-25)25 Maret 1942Memphis, Tennessee, A.S.Meninggal16 Agustus 2018(2018-08-16) (umur 76)Detroit, Michigan, A.S.Sebab meninggalKanker pankreasPekerjaan Penyanyi pengarang lagu pianis Tahun aktif1956–2017Kota asalDetroit, Michigan, A.S.Suami/istriTed White ​ ​(m. 1961; cer 1969)​ Glynn Turman ​ ​(m. 1978; cer 1984&#...