1
2
3
A* P=new B; //A是父类,B是子类

虽然P是一个基类的指针。但是new B调用的是派生类B的构造方法,所以构造的是B类对象。先调用A的构造函数,再调用B的构造函数。构造完后会返回B类对象的地址,然后将它赋给一个基类指针P。
1
B* q=new B;//这里和上面唯一的区别就是,将B类对象的地址赋给了派生类指针q

而需要注意的是:可以将一个派生类对象的地址赋给基类指针和派生类指针,而一个基类对象的地址只能赋给基类指针,不能赋给派生类的指针。因为派生类不但拥有基类的方法属性,还有基类没有的属性方法。

将一个地址赋给一个指针前,通常会将该地址处的对象类型转换为指针所指的类型。而将一个基类地址赋给一个派生类指针是不允许的,如果可以的话,那么这个指针就可以调用派生类的方法和属性。但指针指向的是一个基类对象,而基类可能并没有这些方法和属性,因为这些方法和属性是派生类新增的,所以,基类地址赋给一个派生类指针是不允许的。但将一个派生类对象的地址赋给一个基类指针是可以的,因为,基类指针能调用的方法和属性,派生类都有,所以并不会有什么问题。

动态多态

子类重写虚函数以完成具体功能,用户通过指向基类的引用或指针来操作这些对象,对虚函数的调用会自动绑定到实际提供的子类对象上去。

动态多态是在运行时完成的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
namespace DynamicPoly
{
class Geometry // base class
{
public:
virtual void Draw()const = 0;
};

class Line : public Geometry // 1
{
public:
virtual void Draw()const{ std::cout << "Line Draw()\n"; }
};

class Circle : public Geometry // 2
{
public:
virtual void Draw()const{ std::cout << "Circle Draw()\n"; }
};

class Rectangle : public Geometry // 3
{
public:
virtual void Draw()const{ std::cout << "Rectangle Draw()\n"; }
};

void DrawGeometry(const Geometry *geo) // 基类指针
{
geo->Draw(); // 多态
}

//动态多态最吸引人之处在于处理异质对象集合的能力
void DrawGeometry(std::vector<DynamicPoly::Geometry*> vecGeo)
{
const size_t size = vecGeo.size();
for(size_t i = 0; i < size; ++i)
vecGeo[i]->Draw();
}
}

void test_dynamic_polymorphism()
{
DynamicPoly::Line line;
DynamicPoly::Circle circle;
DynamicPoly::Rectangle rect;
DynamicPoly::DrawGeometry(&circle); // circle::draw

std::vector<DynamicPoly::Geometry*> vec;
vec.push_back(&line);
vec.push_back(&circle);
vec.push_back(&rect);
DynamicPoly::DrawGeometry(vec);
}

静态多态

编译期多态。

静态多态本质上是模板的具现化,

例:

1
2
3
4
5
6
7
8
9
10
template<typename Widget,typename Other>
void DoSomething(Widget& w, const Other& someNasty)
{
if( w.size() > 0 && w != someNasty) //someNastyT可能是是T类型的某一实例,也可能不是
{
Widget temp(w);
temp.normalize();
temp.swap(w);
}
}

代码要求:

  1. 类型T支持size、normalize、swap、拷贝构造、!=运算符

  2. 类型T在编译模板进行具现化时才表现为调用不同函数

Reference

https://www.cnblogs.com/lizhenghn/p/3667681.html