Herança múltipla em C ++
Se uma classe C ++ pode herdar de outro, então surge a questão imediatamente ", uma classe pode herdar de duas (ou mais) aulas?" O em resposta é um incondicional "sim".
Pode ser útil para ver um exemplo do mundo real de herança múltipla entender por que isso é uma capacidade vale a pena ter. A maioria das universidades oferecem empregos para estudantes de graduação como assistentes de ensino. Estes indivíduos são ainda estudantes e tem todas as propriedades de um aluno - mas, além disso, eles também são oferecidas as características de um instrutor. Assim, logicamente, a sua árvore de herança parece com isso:
Expressa em C ++, isso iria aparecer da seguinte forma:
classe Student {public: GPA double () - bool se inscrever (Curso) pay -bool (dólares duplas) -} - classe instrutor {public: grau duplo (Artefato) -bool ensinar (claro) -bool GetPaid (dólares duplos) -} TeachingAssistant de classe: Estudante pública, Instrutor pública {public: conselheiro Instructor (Instrutor) -Instructor conselheiro () -} -
A única diferença entre este exemplo e exemplos de herança simples, é o aparecimento de dois nomes de classe após a declaração de Professor assistente.
Dadas as definições de classe apenas mostrados, todos os seguintes podem ser ditas:
TeachingAssistant ta - // obter um grau como um d studentdouble = ta.gpa () - // grau um papel como um instructorta.grade (documento) - // posso passar uma ta para uma função que espera uma festa Studentvoid (Student ) -party (ta) - // ou uma função que espera um sarau Instructorvoid (Instrutor) -soiree (ta) -
Por enquanto, tudo bem. O que há para não gostar sobre a herança múltipla?
vários ambiguidades
Revendo Aluna e Instrutor aulas, essas duas classes de acções de uma propriedade: um número de identificação atribuído pelo universidade. Mas se você tentar adicionar esta propriedade da seguinte forma, você não ganha nada, mas as queixas de C ++:
classe Student {public: IntID () - double GPA () - bool se inscrever (Curso) pay -bool (dólares duplas) -} - classe instrutor {public: int id () - duplo grau (Artefato) -bool ensinar (Curso) -bool GetPaid (dólares duplas) -} - classe TeachingAssistant: Estudante pública, Instrutor pública {public: conselheiro Instructor (Instrutor) -Instructor conselheiro () -
};
Este problema é mostrado graficamente, aqui:
O problema é que agora, quando você diz algo como
TeachingAssistant ta-cout lt; lt; "ID do TA é" lt; lt; ta.id () - // que id?
qual identidade() destina-se - o que um Professor assistente herda de Aluna ou o que ele herda de Instrutor? A ambiguidade pode ser resolvida especificando o caminho para identidade (Conhecido como nome qualificado) como isso:
cout lt; lt; "TA ID de estudante é" lt; lt; ta.Student :: id () -
Agora não há nenhuma ambiguidade. Ao especificar a classe base, C ++ é dito que identidade() escolher.
Resolver a ambigüidade: Primeira tentativa
Mas e se as duas instâncias de identidade() estamos não diferente? Suponha que, como muitas universidades, uma universidade particular, atribui um número de identificação único para os alunos e instrutores. Nesse caso, o que está realmente queria é a situação mostrada na imagem a seguir: Agora, um Professor assistente mas tem uma única identidade() propriedade.
Para tentar expressar esse estado de coisas em C ++, suponha que o seguinte está escrito:
classe Academic {public: int id () -} - classe Student: Academic pública {public: GPA double () - bool se inscrever (Curso) pay -bool (dólares duplas) -} - instrutor de classe: Academic pública {public: grau de casal (Artefato) -bool ensinar (Curso) -bool GetPaid (dólares duplas) -} - classe TeachingAssistant: Estudante pública, Instrutor pública {public: Instrutor conselheiro (Instrutor) -Instructor conselheiro () -} -
Infelizmente (e surpreendentemente), esta abordagem não resolve o problema. Uma referência a ta.id () ainda é ambígua. Acontece que este código não cria a imagem-anterior em vez disso, ele cria a situação mostrada aqui:
Parece que Professor assistente agora herda acadêmico duas vezes - uma vez através da sua Aluna-Ness, e mais uma vez através da sua Instrutor-ness. Tem agora um Estudante :: Academic id :: () e um Instrutor :: Academic id :: ().
Resolver a ambigüidade
A fim de alcançar o que aparece na terceira figura deste artigo em C ++, você deve voltar a cair chamadas algo C ++ herança virtual. Esta característica aparece em ação como se segue:
classe TeachingAssistant: Estudante pública virtual, instrutor público virtual {public: conselheiro Instructor (Instrutor) -Instructor conselheiro () -} -
O uso do virtual palavra-chave diz C ++ para combinar qualquer base de classes comuns que Aluna e Instrutor pode compartilhar. O que se segue não gera um erro do compilador:
cout lt; lt; "TA ID de estudante é" lt; lt; ta.id () - // nenhum erro agora
Com a herança virtual, Professor assistente herda uma e apenas uma cópia do acadêmico ea referência a ta.id () não é ambígua.