当前位置: 首页 > news >正文

详解c++菱形继承和多态---下

菱形继承

#include<iostream>using namespace std;
class Animal
{
public:int m_Age;
};
class Sheep : public Animal {};
class Tuo : public Animal {};
class SheepTuo : public Sheep, public Tuo {};
void test()
{SheepTuo st;st.Sheep::m_Age = 18;st.Tuo::m_Age = 20;cout << "st.Sheep::m_Age: " << st.Sheep::m_Age << endl;cout << "st.Tuo::m_Age: " << st.Tuo::m_Age << endl;}
int main()
{test();return 0;
}

菱形继承数据存在二义性问题。

cl /d1 reportSingleClassLayoutSheepTuo test.cpp

虚继承 

class Sheep : virtual public Animal {};
class Tuo : virtual public Animal {};
class SheepTuo : public Sheep, public Tuo {};

多态

动态多态

满足条件

1.有继承关系

2.子类重写父类的虚函数

使用

父类的指针或引用执行子类对象。

重写

函数返回值类型,函数名,参数列表完全一致。

class Animal
{
public:virtual void speak(){cout << "Animal speak()" << endl;}
};
class Cat : public Animal
{
public:void speak(){cout << "Cat speak()" << endl;}
};
void doSpeak(Animal& animal)
{animal.speak();
}
void test()
{Cat cat;doSpeak(cat);
}

Animal类的大小为4,不加virtual大小为1(空类的大小为1)。

子类重写父类的虚函数,子类的虚函数表内部会替换为子类的虚函数地址。

class AbstractCalculator
{
public:virtual int getResult(){return 0;}int m_Num1;int m_Num2;
};
class AddCalculator :public AbstractCalculator
{
public:int getResult(){return m_Num1 + m_Num2;}
};
class SubCalculator :public AbstractCalculator
{
public:int getResult(){return m_Num1 - m_Num2;}
};
void test()
{AbstractCalculator* ac = new AddCalculator;ac->m_Num1 = 1;ac->m_Num2 = 2;cout << ac->getResult() << endl;
}

纯虚函数和抽象类

class AbstractDrinking
{
public:virtual void Boil() = 0;virtual void Brew() = 0;virtual void PourInCup() = 0;virtual void PutSomething() = 0;void makeDrink(){Boil();Brew();PourInCup();PutSomething();}
};
class Coffee :public AbstractDrinking
{virtual void Boil() { cout << "Boil Coffee" << endl; };virtual void Brew() { cout << "Brew Coffee" << endl; };virtual void PourInCup() { cout << "PourInCup Coffee" << endl; };virtual void PutSomething() { cout << "PutSomething Coffee" << endl; };
};
void doWork(AbstractDrinking* ad)
{ad->makeDrink();
}

虚析构和纯虚析构 

父类指针在析构的时候,不会调用子类中的析构函数,导致如果子类有堆区属性会出现内存泄漏。

class Animal
{
public:Animal(){cout << "Animal()" << endl;}virtual ~Animal(){cout << "~Animal()" << endl;}virtual void speak() = 0;
};
class Cat : public Animal
{
public:Cat(string name){cout << "Cat()" << endl;m_Name = new string(name);}void speak(){cout <<*m_Name<< "Cat speak()" << endl;}~Cat(){if (m_Name != nullptr){cout << "~Cat()" << endl;delete m_Name;m_Name = nullptr;}}string* m_Name;
};
void test()
{Animal* animal = new Cat("Tom");animal->speak();delete animal;
}

通过虚析构解决。

纯虚析构

virtual ~Animal() = 0;
Animal::~Animal()
{cout << "virtual ~Animal()" << endl;
}

需要有声明及实现。

总结

虚基表中存偏移量,用于计算X中虚基类XX对象的位置。

虚基表和虚表通常存在常量区。 

http://www.lryc.cn/news/441460.html

相关文章:

  • python学习笔记目录
  • 非结构化数据中台架构设计最佳实践
  • 鹏鼎控股社招校招入职SHL综合能力测评:高分攻略及真题题库解析答疑
  • 【测向定位】差频MUSIC算法DOA估计【附MATLAB代码】
  • 智能车镜头组入门(四)元素识别
  • Java键盘输入语句
  • 【读书笔记-《30天自制操作系统》-22】Day23
  • C++学习笔记(33)
  • 智谱清影 -CogVideoX-2b-部署与使用,带你揭秘生成6s视频的极致体验!
  • 探索Java中的设计模式:原则与实例
  • 【Java】关键字-static【主线学习笔记】
  • 数字自然资源领域的实现路径
  • GitLab邮箱发送邮件:如何实现自动化发信?
  • sqli-labs靶场搭建
  • Leetcode Hot 100刷题记录 -Day14(矩阵置0)
  • 每日刷题(算法)
  • 大牛直播SDK核心音视频模块探究
  • gin配置swagger文档
  • 基于ssm的快餐店点餐系统设计与实现
  • 集合框架底层使用了什么数据结构
  • Activiti7《第二式:破剑式》——工作流中的以柔克刚
  • docker快速搭建kafka
  • 基于 onsemi NCV78343 NCV78964的汽车矩阵式大灯方案
  • OpenAl o1论文:Let’s Verify Step by Step 快速解读
  • Errorresponsefromdaemon:toomanyrequests:Youhavereachedyourpullratelimit.
  • [2025]医院健康陪诊系统(源码+定制+服务)
  • Golang | Leetcode Golang题解之第405题数字转换为十六进制数
  • VB中如何使用正则表达式(Regular Expressions)
  • Docker FROM 指定基础镜像
  • 19:I2C一:程序模拟I2C通信时序