菱形继承
#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对象的位置。
虚基表和虚表通常存在常量区。