0
点赞
收藏
分享

微信扫一扫

【C++初阶】多态

深夜瞎琢磨 2022-01-27 阅读 76

目录

多态的条件 

析构函数的重写 

C++11 override 和 final

1.final:修饰虚函数,表示该虚函数不能再被重写

2.override: 检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错

重载、覆盖(重写)、隐藏(重定义)的对比

抽象类

多态的原理

虚函数表

多态的原理

单继承和多继承关系的虚函数表 

单继承中的虚函数表


多态的条件 

class Person
{
public:
	virtual void BuyTicket()
	{
		cout << "正常排队—全价买票" << endl;
	}
protected:
	int _age;
	string _name;
};
class Student:public Person
{
public:
	virtual void BuyTicket()
	{
		cout << "正常排队—半价买票" << endl;
	}
protected:
	int _age;
	string _name;
};
class Solider:public Person
{
public:
	virtual void BuyTicket()
	{
		cout << "优先排队—全价买票" << endl;
	}
protected:
	int _age;
	string _name;
};
//多态两个条件
//1,子类重写父类的虚函数
//2,必须是父类的指针或者引用去调用虚函数
void Func(Person* ptr)
{
	//多态—ptr指向父类对象调用父类的虚函数,指向子类对象调子类虚函数
	ptr->BuyTicket();
}
int main()
{
	Person ps;
	Student st;
	Solider sd;

	Func(&ps);
	Func(&st);
	Func(&sd);
}

析构函数的重写 

class Person
{
public:
	virtual ~Person()
	{
		cout << "~Person()" << endl;
	}
};
class Student :public Person
{
public:
	virtual ~Student()
	{
		cout << "~Student()" << endl;
	}
};
//如果不是虚函数,他们之间是隐藏关系
//是虚函数,他们是重写关系
int main()
{
	普通场景下面,虚函数是否重写都是OK的
	//Person p;
	//Student s;
	//new对象特殊场景
	Person* p1 = new Person;
	Person* p2 = new Student;

	delete p1;//p1->destructor()
	delete p2;//p2->destructor()
	return 0;
}

C++11 override 和 final

1.final:修饰虚函数,表示该虚函数不能再被重写

2.override: 检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错

class Car{
public:
	virtual void Drive(){}
};
class Benz :public Car {
public:
	virtual void Drive() override { cout << "Benz-舒适" << endl; }
};

重载、覆盖(重写)、隐藏(重定义)的对比

抽象类

class Car
{
public:
	virtual void Drive() = 0;
};
class Benz :public Car
{
public:
	virtual void Drive()
	{
		cout << "Benz-舒适" << endl;
	}
};
class BMW :public Car
{
public:
	virtual void Drive()
	{
		cout << "BMW-操控" << endl;
	}
};
void Test()
{
	Car* pBenz = new Benz;
	pBenz->Drive();
	Car* pBMW = new BMW;
	pBMW->Drive();
}

多态的原理

虚函数表

虚函数表:

如下代码的输出结果是?

class Base
{
public:
	virtual void Func1()
	{
		cout << "Func1()" << endl;
	}
private:
	int _b = 1;
};
int main()
{
	Base b;
	cout << sizeof(Base) << endl;
	return 0;
}

 在看一段代码:

class Base
{
public:
	virtual void Func1()
	{
		cout << "Base::Func1()" << endl;
	}
	virtual void Func2()
	{
		cout << "Base::Func2()" << endl;
	}
	void Func3()
	{
		cout << "Base::Func3()" << endl;
	}
private:
	int _b = 1;
};
class Derive : public Base
{
public:
	virtual void Func1()
	{
		cout << "Derive::Func1()" << endl;
	}
private:
	int _d = 2;
};
int main()
{
	Base b;
	Derive d;
	return 0;
}

多态的原理

class Person 
{
public:
	virtual void BuyTicket() { cout << "买票-全价" << endl; }
};
class Student : public Person 
{
public:
	virtual void BuyTicket() { cout << "买票-半价" << endl; }
};
void Func(Person& p)
{
	p.BuyTicket();
}
int main()
{
	Person Mike;
	Func(Mike);
	Student Johnson;
	Func(Johnson);
	return 0;
}

 分析===》

单继承和多继承关系的虚函数表 

单继承中的虚函数表

class Base
{
public:
	virtual void Func1()
	{
		cout << "Base::Func1()" << endl;
	}
	virtual void Func2()
	{
		cout << "Base::Func2()" << endl;
	}
	void Func3()
	{
		cout << "Base::Func3()" << endl;
	}
	private:
		int _b = 1;
	};
class Derive : public Base
{
public:
	virtual void Func1()
	{
		cout << "Derive::Func1()" << endl;
	}
	virtual void Func4()
	{
		cout << "Derive::Func4()" << endl;
	}
private:
	int _d = 2;
};
typedef void(*VFPTR)();
//打印虚表
void PrintVFT(void* vft[])
{
	printf("%p\n",vft);
	for (size_t i = 0; vft[i] != nullptr; i++)
	{
		printf("vft[%d]:%p->",i,vft[i]);
		VFPTR f = (VFPTR)vft[i];
		f();
	}
	printf("\n");
}
int main()
{
	Base b;
	Derive d;
	PrintVFT((void**)*(int*)&b);
	PrintVFT((void**)*(int*)&d);

	return 0;
}

int main()
{
	Base bb;
	int a = 0;
	int* p1 = new int;
	const char* p2 = "hello world";
	auto pf = PrintVFT;
	static int b = 1;
	printf("栈祯变量:%p\n",&a);
	printf("堆变量:%p\n", p1);
	printf("常量区变量:%p\n", p2);
	printf("函数地址变量:%p\n", pf);
	printf("静态区变量:%p\n", &b);
	printf("虚函数表地址:%p\n", *(int*)&bb);
	return 0;
}

举报

相关推荐

C++多态

c++多态

C++:多态

【C++】多态

C++ 多态

【C++】初阶模板

0 条评论