minhas informações de contato
Correspondência[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
o que é combinação
(1) Composição significa usar objetos de várias outras classes como membros de uma classe.
(2) Use a árvore de classes para explicar os casos
(3) A combinação também é um método de reutilização de código e sua essência éEstruturaIncluir
#include <iostream>
#include <vector>
#include <string>
// Leaf 类
class Leaf {
public:
Leaf(const std::string& color) : color_(color) {
std::cout << "Leaf constructor called: " << color_ << std::endl;
}
~Leaf() {
std::cout << "Leaf destructor called: " << color_ << std::endl;
}
void display() const {
std::cout << "Leaf color: " << color_ << std::endl;
}
private:
std::string color_;
};
// Branch 类
class Branch {
public:
Branch(int length) : length_(length) {
std::cout << "Branch constructor called: " << length_ << " cm" << std::endl;
}
~Branch() {
std::cout << "Branch destructor called: " << length_ << " cm" << std::endl;
}
void display() const {
std::cout << "Branch length: " << length_ << " cm" << std::endl;
}
private:
int length_;
};
// Tree 类,包含 Leaf 和 Branch 对象
class Tree {
public:
Tree(const std::string& leafColor, int branchLength)
: leaf_(leafColor), branch_(branchLength) {
std::cout << "Tree constructor called" << std::endl;
}
~Tree() {
std::cout << "Tree destructor called" << std::endl;
}
void display() const {
leaf_.display();
branch_.display();
}
private:
Leaf leaf_;
Branch branch_;
};
int main() {
Tree tree("Green", 150);
tree.display();
return 0;
}
Comparação das características de herança e composição
(1) Herança é uma espécie de (é a) A relação é transitiva e não simétrica.
(2) A combinação é a relação de uma parte de (tem um),
(3) Herança é reutilização de caixa branca. Como a herança de classe nos permite substituir os detalhes de implementação da classe pai de acordo com nossa própria implementação, a implementação da classe pai fica visível para a classe filha.
(4) O recurso de reutilização de caixa branca da herança destrói o recurso de encapsulamento da classe até certo ponto, porque exporá os detalhes de implementação da classe pai à subclasse.
(5) A combinação pertence à reutilização de caixa preta.Os detalhes internos do objeto contido não são visíveis para o mundo exterior, portanto seu encapsulamento é relativamente bom e a interdependência na implementação é relativamente pequena.
(6) A classe incluída na combinação será criada e destruída à medida que a classe que a contém é criada. As combinações são reutilizadas em caixa preta e podem ser definidas dinamicamente em tempo de execução, obtendo outras referências de objetos ou ponteiros do mesmo tipo. A desvantagem é que existem muitos objetos no sistema.
(7) O princípio de design OO é combinar primeiro e depois herdar.
herança múltipla
(1) Herança múltipla significa que uma subclasse possui várias classes pai
(2)Demonstração de herança múltipla
(3) Não há diferença óbvia entre os princípios da herança múltipla e da herança única.
(4) Herança múltipla pode levar a problemas de ambiguidade
A ambigüidade da herança múltipla 1
(1) Cenário: C tem herança múltipla de A e B, portanto haverá ambigüidade ao chamar membros com os mesmos nomes de A e B em C.
(2) Motivo: C herda um membro com o mesmo nome (domínio de namespace diferente) de A e B, portanto, ao chamar com um objeto de C, o compilador não pode determinar qual deles queremos chamar.
(3) Solução 1: Para evitar a ocorrência, deixe que a nomenclatura dos membros públicos de A e B não entre em conflito repetidamente. Mas isso às vezes é incontrolável.
(4) Solução 2: Especifique claramente qual chamar durante a codificação, use cA::func() para especificar claramente que a função da classe A é chamada em vez da função da classe B.
(5) Solução 3: Redefina func em C, então a função em C será chamada e a função em A e B será ocultada.
(6) Resumo: Pode ser resolvido, mas não existe uma boa solução.
A ambigüidade da herança múltipla 2
(1) Cenário: problema de herança de diamantes.Ou seja, A é a classe ancestral, B1:A, B2:A, C:B1,B2. Neste momento, haverá ambigüidade ao usar o objeto de C para chamar um método em A.
(2) Análise: c.func() é ambíguo, cA::func() também é ambíguo, mas c.B1::func() e c.B2::func() não são ambíguos
(3) Solução: Igual ao problema 1, mas o problema 2 é mais sutil e mais difícil de evitar
// 祖类
class Aa {
public:
void show() { std::cout << "A's method" << std::endl; }
};
// 派生类 B1 和 B2,从 A 继承
class B1 : public Aa {
public:
void show() { std::cout << "B1's show" << std::endl; }
void showB1() { std::cout << "B1's method" << std::endl; }
};
class B2 : public Aa {
public:
void show() { std::cout << "B2's show" << std::endl; }
void showB2() { std::cout << "B2's method" << std::endl; }
};
// 派生类 C,从 B1 和 B2 继承
class C : public B1, public B2 {
public:
void showC() { std::cout << "C's method" << std::endl; }
};
int test070103() {
C c;
// c.Aa::show(); // 调用 A 的方法 不可以
c.Aa::B1::show(); // 调用 A 的方法 不可以
c.B2::Aa::show(); // 调用 A 的方法 不可以
c.B1::show(); // 调用 B1 的方法
c.B2::show(); // 调用 B2 的方法
c.showB1(); // 调用 B1 的方法
c.showB2(); // 调用 B2 的方法
c.showC(); // 调用 C 的方法
return 0;
}
Como usar herança virtual
(1) Cenário: A herança diamante leva a problemas de ambiguidade. Essencialmente, existem dois objetos A contidos em B1 e B2 na classe neta C, portanto, há ambiguidade.
(2) Solução de herança virtual: deixe B1 e B2 herdarem A virtualmente e então C poderá herdar B1 e B2 normalmente.
(3) A herança virtual é simples assim. Ela é criada para resolver o problema de ambiguidade da herança de diamante. Não tem relação direta com funções virtuais (para obter recursos polimórficos).
O princípio de implementação da herança virtual
(1) O princípio da herança virtual é: ponteiro de tabela de classe base virtual vbptr e tabela de classe base virtual tabela virtual
(2)Referência:https://blog.csdn.net/xiejingfa/article/details/48028491
Entenda o que é combinação. Existem muitas variáveis de membro de outros tipos de classe em uma classe.
Entenda a diferença entre composição e herança
Ambiguidade: Se você executar uma função, pode não ser necessariamente aquela que você deseja especificar.
Solução: Use cA::func() para especificar explicitamente a classe que está sendo chamada
A herança virtual é um pouco como a compilação condicional. Ela só precisa ser introduzida uma vez. Não precisa ser introduzida repetidamente para obter o efeito de introdução.
Os registros do estudo e os contatos de infração serão excluídos.
Fonte: Sala de aula de Internet das Coisas do professor Zhu