【c++】多态&多态对象模型
来源:互联网 发布:算法导论 原版 编辑:程序博客网 时间:2024/06/05 18:33
1.多态:
在C ++程序设计中,多态性是指具有不同功能的函数可以用同一个函数名,这样就可以用一个函数名调用不同内容的函数。在面向对象方法中一般是这样表述多态性的:向不同的对象发送同一个消息, 不同的对象在接收时会产生不同的行为(即方法)。也就是说,每个对象可以用自己的方式去响应共同的消息。所谓消息,就是调用函数,不同的行为就是指不同的实现,即执行不同的函数。从系统实现的角度看,多态性分为两类:静态多态性和动态多态性。以前学过的函数重载和运算符重载实现的多态性属于静态多态性,在程序编译时系统就能决定调用的是哪个函数,因此静态多态性又称编译时的多态性。静态多态性是通过函数的重载实现的(运算符重载实质上也是函数重载)。动态多态性是在程序运行过程中才动态地确定操作所针对的对象。它又称运行时的多态性。动态多态性是通过虚函数(Virtual fiinction)实现的。
当使用基类的指针或引用调用重写的虚函数时,当指向父类调用的就是父类的虚函数,当指向子类调用的就是子类的虚函数。
例:
class Person //父类
{
public:
virtual void BuyTickets()
{
cout << "买票" << endl;
}
protected:
string _name;
};
class Student :public Person //子类
{
public:
virtual void BuyTickets()
{
cout << "买票-半价" << endl;
}
protected:
int _num; //学号
};
void fun(Person&p)
{
p.BuyTickets();
}
void test()
{
Person p;
Student s;
fun(p);
fun(s);
}
虚函数:类成员函数前加virtual
虚函数重写:当在子类定义了一个与父类完全相同的虚函数,则称子类的这个函数重写了父类这个函数。
2.多态的对象模型(单继承&多继承)
1.单继承
class Base
{
public:
virtual void func1()
{
cout << "Base::func1" << endl;
}
virtual void func2()
{
cout << "Base::func2" << endl;
}
private:
int a;
};
class Derive :public Base
{
public:
virtual void func1()
{
cout << "Derive::func1" << endl;
}
virtual void func3()
{
cout << "Derive::func3" << endl;
}
virtual void func4()
{
cout << "Derive::func4" << endl;
}
private:
int b;
};
typedef void(*FUNC)();
void PrintVTable(int *VTable)
{
cout << "虚表地址:" << VTable << endl;
for (int i = 0; VTable[i] != 0; ++i)
{
printf("第%d个虚函数地址:0X%x,->", i, VTable[i]);
FUNC f = (FUNC)VTable[i];
f();
}
cout << endl;
}
void Test1()
{
Base b1;
Derive d1;
int*VTable1 = (int*)(*(int*)&b1);
int*VTable2 = (int*)(*(int*)&d1);
PrintVTable(VTable1);
PrintVTable(VTable2);
}
可以看出派生类Derive::fun1重写基类Base::fun1,覆盖了相应虚表位置上的函数。
2.多继承
class Base1
{
public:
virtual void func1()
{
cout << "Base::func1" << endl;
}
virtual void func2()
{
cout << "Base::func2" << endl;
}
private:
int b1;
};
class Base2
{
public:
virtual void func1()
{
cout << "Base::func1" << endl;
}
virtual void func2()
{
cout << "Base::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;
};
typedef void(*FUNC)();
void PrintVTable(int *VTable)
{
cout << "虚表地址:" << VTable << endl;
for (int i = 0; VTable[i] != 0; ++i)
{
printf("第%d个虚函数地址:0X%x,->", i, VTable[i]);
FUNC f = (FUNC)VTable[i];
f();
}
cout << endl;
}
void Test1()
{
Derive d1;
int*VTable = (int*)(*(int*)&d1);
PrintVTable(VTable);
//Base2虚函数表在对象Base1后面
VTable = (int*)(*((int*)&d1 + sizeof(Base1) / 4));
PrintVTable(VTable);
}
内存布局:
3.菱形继承
什么是菱形继承?通过这个图大家就可以很直观的理解啦
如上图,菱形继承即多个类继承了同一个公共基类,而这些派生类又同时被一个类继承。这么做会引发什么问题呢?
通过该代码,我们可以看出当我们想要调用我们从Base里继承的fun时就会出现调用不明确问题,并且会造成数据冗余的问题。
我们可以使用域限定我们所要访问的函数,c++也给我们了另一个解决方案--虚继承。
- 【c++】多态&多态对象模型
- C++_多态&多态的对象模型
- 【C++】多态及其对象模型
- 多态&多态对象模型
- 多态&多态对象模型
- 多态&多态对象模型
- 多态&多态对象模型
- 多态&多态对象模型
- 多态&多态对象模型
- 多态&多态对象模型
- 多态+多态对象模型
- 多态+多态对象模型
- 多态&多态对象模型
- 多态+多态对象模型
- 多态对象模型
- Objective-C对象模型
- Objective-C对象模型
- objective C 对象模型
- 调度器的定时器
- hibernate加载hibernate.cfg.xml文件
- H
- 【数据结构基础]】数据库练习题
- Android开发学习(2)环境搭建及基本组件
- 【c++】多态&多态对象模型
- ebtables与iptables的区别(ebtables的简单应用)
- MongoDB的存储结构及对空间使用率的影响
- git 常用命令
- HDU 1312 Red and Black <BFS>
- Sublime Text3 Install Package报错“There are no packages available for installation”
- 还没过时的用户体验设计趋势
- Shell 命令行求两个文件每行对比的相同内容
- 通过Unity2D独立开发一款瓷砖式RPG游戏需要学习哪些知识?