C++ 的多态性据前辈们所说,是非常难以理解的一部分内容,虽然他实现很简单,但是套用到各种设计模式后,你会非常难以理解,但无论怎样,笔者始终认为,如果了解了内部的实现原理,实际就不会那么难了。本文将介绍虚函数表的相关内容,阐述了它与多态之间难以割舍的关系。

Continue reading

上一篇文章中,我们看到了简单的赋值兼容模型,将子类赋值给父类对象时,调用共有的同名接口时,调用的依然还是父类的成员函数。在 C++ 中,有一个总要的概念,那就是多态。通过父类提供一些虚函数,让子类继承下去并实现为另外的功能,然后将子类对象的地址赋值给父类的对象指针。这样再次使用父类的指针调用共有同名接口时,你会发现它竟然调用的是子类的方法。这一切都来源于一个关键字“virtual”。

Continue reading

C++ 中,类型的匹配检测是非常严格的,但是你会发现一个现象,如果一个类继承了另外一个类,把子类的对象赋值给父类的时候,系统不但不提示错误,而且程序还能顺利的编译通过并运行。这其实就是 C++ 内部提供的赋值兼容的过程,但是要注意,如果子类数据成员比父类多,则会出现数据截断。具体表现形式如下图:

Continue reading

shadow(阴影)、overload(重载)、override(覆写),这三个概念一直有人非常混淆,很幸运,经过老师的悉心教导,我总结了一下三个概念的不同之处。

shadow:发生在父子之间,需要函数名相同即可构成 shadow (阴影),构成 shadow 后可通过域运算符来访问对应类中的函数。

#include <iostream>

using namespace std;

class A
{
public:
	void display()
	{
		cout << "A display" << endl;
	}
};

// B 继承了 A
class B : public A
{
public:
	void display()
	{
		cout << "B display" << endl;
	}
};

int main(int argc, char* argv[])
{
	B b;
	b.display();
	// 域运算符来访问对应类中的函数
	b.A::display();

	return 0;
}

overload:发生在同一作用域内(同一个类中)。同名,参数不同(类型、个数、顺序)无关返回值就会构成 overload (重载)。

#include <iostream>

using namespace std;

class A
{
public:
	void display()
	{
		cout << "A display" << endl;
	}
	// 构成重载
	void display(int i)
	{
		cout << "A display int" << endl;
	}
};

int main(int argc, char* argv[])
{
	A a;
	a.display();
	a.display(10);

	return 0;
}

override:发生在派生类中,实现了父类的虚函数成为 override(覆写),需要函数名、返回值、参数个数及类型都一模一样,函数体可以不同。虚函数在后面会有详细介绍。

#include <iostream>

using namespace std;

class A
{
public:
	virtual void display()
	{
		cout << "A display" << endl;
	}
};

class B : public A
{
public:
	// 继承了A类,
	void display()
	{
		cout << "B display" << endl;
	}
};

int main(int argc, char* argv[])
{
	// 多态小例子

	A *a = new B;
	a->display();

	return 0;
}