Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Aprenda Herança Diamante | Visão Geral de Herança
C++ Poo
course content

Conteúdo do Curso

C++ Poo

C++ Poo

1. Fundamentos de POO em C++
2. Construtores e Destrutores
3. Visão Geral do Encapsulamento
4. Visão Geral de Herança
5. Visão Geral do Polimorfismo

book
Herança Diamante

A herança múltipla pode levar a uma situação conhecida como problema do diamante ou herança em diamante, que é um desafio significativo em linguagens de programação orientadas a objetos que suportam herança múltipla.

Isso ocorre quando uma subclasse herda de duas ou mais classes, que por sua vez herdam de uma superclasse comum. O termo diamante é utilizado porque o esquema de herança se assemelha ao formato de um diamante.

main.cpp

main.cpp

copy
1234567
class Base {}; class Derived1 : public Base {}; class Derived2 : public Base {}; class Diamond : public Derived1, public Derived2 {};

O principal problema da herança em diamante é a ambiguidade que ela cria. Como Diamond herda tanto de Derived1 quanto de Derived2, que por sua vez herdam de Base, existem duas cópias de Base dentro de um objeto de Diamond. Isso pode gerar ambiguidade.

main.cpp

main.cpp

copy
12345678910111213141516
#include <iostream> class Base { public: void display() { std::cout << "Base display()" << std::endl; } }; class Derived1 : public Base { }; class Derived2 : public Base { }; class Diamond : public Derived1, public Derived2 { }; int main() { Diamond obj; obj.display(); // Ambiguity: Which display() method should be called? }

Solução para o problema

A palavra-chave virtual ajuda a evitar esse problema. É possível resolver essa ambiguidade por meio de herança virtual utilizando a palavra-chave virtual. Quando Diamond herda virtualmente, o C++ garante que apenas uma cópia da superclasse esteja presente, mesmo que seja herdada várias vezes por caminhos diferentes.

main.cpp

main.cpp

copy
1234567
class Base {}; class Derived1 : virtual public Base {}; class Derived2 : virtual public Base {}; class Diamond : public Derived1, public Derived2 {};
Note
Nota

Tente resolver o problema de ambiguidade no exemplo anterior utilizando herança virtual.

Implementação da Herança Diamante

Para implementar a herança diamante de forma eficaz, utilize a palavra-chave virtual na declaração da superclasse dentro das classes intermediárias. Garanta o uso consistente da herança virtual em todos os caminhos da hierarquia de herança e atente-se à ordem de chamadas dos construtores e destrutores.

Resolução de Ambiguidades

Um dos desafios da herança múltipla é também lidar com possíveis ambiguidades quando há membros com os mesmos nomes.

main.cpp

main.cpp

copy
12345678910111213141516171819
#include <iostream> class Base {}; class Derived1 : public Base { public: void display() { std::cout << "Derived1 display()" << std::endl; } }; class Derived2 : public Base { public: void display() { std::cout << "Derived2 display()" << std::endl; } }; class Diamond : public Derived1, public Derived2 { }; int main() { Diamond obj; obj.display(); // Ambiguity: Which display() method should be called? }

Se ambas as superclasses possuírem membros com o mesmo nome, a subclasse pode não saber qual deles utilizar. Para resolver essas ambiguidades, é possível utilizar o operador de resolução de escopo (::) para especificar qual membro da classe base deve ser acessado. Por exemplo:

main.cpp

main.cpp

copy
1234567891011121314151617181920
#include <iostream> class Base {}; class Derived1 : public Base { public: void display() { std::cout << "Derived1 display()" << std::endl; } }; class Derived2 : public Base { public: void display() { std::cout << "Derived2 display()" << std::endl; } }; class Diamond : public Derived1, public Derived2 { }; int main() { Diamond obj; obj.Derived1::display(); obj.Derived2::display(); }
question mark

Qual é o principal problema causado pela herança diamante?

Select the correct answer

Tudo estava claro?

Como podemos melhorá-lo?

Obrigado pelo seu feedback!

Seção 4. Capítulo 5

Pergunte à IA

expand

Pergunte à IA

ChatGPT

Pergunte o que quiser ou experimente uma das perguntas sugeridas para iniciar nosso bate-papo

course content

Conteúdo do Curso

C++ Poo

C++ Poo

1. Fundamentos de POO em C++
2. Construtores e Destrutores
3. Visão Geral do Encapsulamento
4. Visão Geral de Herança
5. Visão Geral do Polimorfismo

book
Herança Diamante

A herança múltipla pode levar a uma situação conhecida como problema do diamante ou herança em diamante, que é um desafio significativo em linguagens de programação orientadas a objetos que suportam herança múltipla.

Isso ocorre quando uma subclasse herda de duas ou mais classes, que por sua vez herdam de uma superclasse comum. O termo diamante é utilizado porque o esquema de herança se assemelha ao formato de um diamante.

main.cpp

main.cpp

copy
1234567
class Base {}; class Derived1 : public Base {}; class Derived2 : public Base {}; class Diamond : public Derived1, public Derived2 {};

O principal problema da herança em diamante é a ambiguidade que ela cria. Como Diamond herda tanto de Derived1 quanto de Derived2, que por sua vez herdam de Base, existem duas cópias de Base dentro de um objeto de Diamond. Isso pode gerar ambiguidade.

main.cpp

main.cpp

copy
12345678910111213141516
#include <iostream> class Base { public: void display() { std::cout << "Base display()" << std::endl; } }; class Derived1 : public Base { }; class Derived2 : public Base { }; class Diamond : public Derived1, public Derived2 { }; int main() { Diamond obj; obj.display(); // Ambiguity: Which display() method should be called? }

Solução para o problema

A palavra-chave virtual ajuda a evitar esse problema. É possível resolver essa ambiguidade por meio de herança virtual utilizando a palavra-chave virtual. Quando Diamond herda virtualmente, o C++ garante que apenas uma cópia da superclasse esteja presente, mesmo que seja herdada várias vezes por caminhos diferentes.

main.cpp

main.cpp

copy
1234567
class Base {}; class Derived1 : virtual public Base {}; class Derived2 : virtual public Base {}; class Diamond : public Derived1, public Derived2 {};
Note
Nota

Tente resolver o problema de ambiguidade no exemplo anterior utilizando herança virtual.

Implementação da Herança Diamante

Para implementar a herança diamante de forma eficaz, utilize a palavra-chave virtual na declaração da superclasse dentro das classes intermediárias. Garanta o uso consistente da herança virtual em todos os caminhos da hierarquia de herança e atente-se à ordem de chamadas dos construtores e destrutores.

Resolução de Ambiguidades

Um dos desafios da herança múltipla é também lidar com possíveis ambiguidades quando há membros com os mesmos nomes.

main.cpp

main.cpp

copy
12345678910111213141516171819
#include <iostream> class Base {}; class Derived1 : public Base { public: void display() { std::cout << "Derived1 display()" << std::endl; } }; class Derived2 : public Base { public: void display() { std::cout << "Derived2 display()" << std::endl; } }; class Diamond : public Derived1, public Derived2 { }; int main() { Diamond obj; obj.display(); // Ambiguity: Which display() method should be called? }

Se ambas as superclasses possuírem membros com o mesmo nome, a subclasse pode não saber qual deles utilizar. Para resolver essas ambiguidades, é possível utilizar o operador de resolução de escopo (::) para especificar qual membro da classe base deve ser acessado. Por exemplo:

main.cpp

main.cpp

copy
1234567891011121314151617181920
#include <iostream> class Base {}; class Derived1 : public Base { public: void display() { std::cout << "Derived1 display()" << std::endl; } }; class Derived2 : public Base { public: void display() { std::cout << "Derived2 display()" << std::endl; } }; class Diamond : public Derived1, public Derived2 { }; int main() { Diamond obj; obj.Derived1::display(); obj.Derived2::display(); }
question mark

Qual é o principal problema causado pela herança diamante?

Select the correct answer

Tudo estava claro?

Como podemos melhorá-lo?

Obrigado pelo seu feedback!

Seção 4. Capítulo 5
some-alt