文章目录
多态概念及其触发条件
重写和协变
(考点1)
这里强调一下,重写重写的是实现。看以下这个场景:(考点)
class A
{
public:
A()
{}
virtual void func(int val = 1)
{
std::cout << "A->" << val << std::endl;
}
virtual void test()
{
func();
}
};
class B : public A
{
public:
void func(int val = 0)
{
std::cout << "B->" << val << std::endl;
}
};
int main()
{
A* p = new B();
p->test();
return 0;
}
(考点2)
那为什么要把析构函数构成重写呢?看以下这个场景:(考点)
class Person {
public:
~Person() { cout << "~Person()" << endl; }
};
class Student : public Person {
public:
~Student() {
cout << "~Student()" << endl;
delete[] ptr;
}
protected:
int* ptr = new int[10];
};
int main()
{
Person* p = new Person;
delete p;
p = new Student;
delete p;
return 0;
}
虚函数表及其位置
(考点3)
这时候我们再反过来思考,为什么一定是父类的指针或者引用,而不能是父类对象?
虚表位置
class Person {
public:
virtual void BuyTicket() const { cout << "成人-全价" << endl; }
};
class Student : public Person {
public:
virtual void BuyTicket() const { cout << "学生-半价" << endl; }
};
int main()
{
Person ps;
Student st;
int a = 0;
printf("栈:%p\n\n", &a);
static int b = 0;
printf("静态区:%p\n\n", &b);
int* p = new int;
printf("堆:%p\n\n", p);
const char* str = "hello world";
printf("常量区:%p\n\n", str);
printf("虚表1:%p\n", *((int*)&ps));
printf("虚表2:%p\n", *((int*)&st));
return 0;
}
多继承中的虚函数表
// 打印函数指针数组
typedef void(*FUNC_PTR) ();
void PrintVFT(FUNC_PTR* table)
{
for (size_t i = 0; table[i] != nullptr; i++)
{
printf("[%d]:%p->", i, table[i]);
FUNC_PTR f = table[i];
f();//这个地址可以调用说明一定是函数
}
printf("\n");
}
class Base1 {
public:
virtual void func1() { cout << "Base1::func1" << endl; }
virtual void func2() { cout << "Base1::func2" << endl; }
private:
int b1;
};
class Base2 {
public:
virtual void func1() { cout << "Base2::func1" << endl; }
virtual void func2() { cout << "Base2::func2" << endl; }
private:
int b2;
};
class Derive : public Base1, public Base2 {
public:
virtual void func1() { cout << "Derive::func1" << endl; }
virtual void func3() { cout << "Derive::func3" << endl; }
private:
int d1;
};
int main()
{
Derive d;
int vft1 = *((int*)&d);
Base2* ptr = &d;
int vft2 = *((int*)ptr);
printf("第一张虚表:\n");
PrintVFT((FUNC_PTR*)vft1);
printf("第二张虚表:\n");
PrintVFT((FUNC_PTR*)vft2);
return 0;
}