示例代码:
#include注意: 出于效率的考虑,没有必要将所有成员函数都声明为虚函数。通过虚函数表指针VPTR调用重写函数是在 程序运行时进行的, 因此需要通过寻址操作才能确定真正应该调用的函数。而普通成员函数 是在编译时就确定了调用的函数。在效率上, 虚函数的效率要低很多。 c.虚函数与多态的关系: 多态是依靠虚函数实现的。但是就算我不想实现多态,依然可以在类中定义虚函数的,类创建对象时,依然产生虚函数表,依然存在VPTR指针。 d.对象在创建的时候由编译器对VPTR指针进行初始化,只有当对象的构造完全结束后VPTR的指向才最终确定,父类对象的VPTR指向父类虚函数表,子类对象的VPTR指向子类虚函数表。 e.构造函数中调用虚函数无法实现多态:说明下这个知识点,是本节的一个疑问。如果有大神路过,希望大神指点下。也希望再日后的学习中,自己可以补充上来!!!对于唐老师的 构造函数与VPTR指针之间的关系分析(唐老师的白板图)、还有那个this指针的举例的观点(唐老师的代码),我有所保留!!!待日后提高!!!这里面有一个不知对错的反例,代码如下:using namespace std; class parent { public: int a; virtual void fun() { cout << "parent fun()" < fun(); return 0; }
#include虽然不确定,但是依然记住构造函数中无法使用虚函数完成多态。using namespace std; class parent { public: parent() { cout << "hello parent()" << endl; } virtual void fun() { cout << "parent fun() " < fun(); } void fun() { cout << "child fun() " << endl; } }; int main() { parent p; child c(&p); child c1(&c); }
6.纯虚函数:
a.面向对象中的抽象类: 抽象类可以用于表示现实世界中的抽象概念。 抽象类是一种只能定义类型,而不能产生对象的类。 抽象类只能被继承并重写相关函数。抽象类的直接特征是纯虚函数。 b.纯虚函数: 只声明函数原型,而故意不定义函数体的虚函数 c.抽象类与纯虚函数: 第一: 抽象类不能定义对象(因为抽象类,就是利用继承,让自己这个父类的纯虚函数进行重写,使得多个子类产生多态的现象),抽象类的目的不是创建对象,而是使子类产生多态。 第二: 抽象类只能定义指针和引用 第三: 抽象类中的纯虚函数必须被子类重写 第四: 因为有纯虚函数的存在,所以类变成了抽象类,因为纯虚函数没有函数体且不能被调用,所以抽象类也不能定义对象(纯虚函数存在的目的,就是让抽象类的子类进行函数重写,从而实现多态),抽象类定义了对象就有可能调用纯虚函数! d.纯虚函数的示例:class shape
{
public:
virtual double area() = 0;
};
注意:area为纯虚函数,= 0 是告诉编译器,这个函数是纯虚函数,故意只声明不定义函数体
示例代码(这是一个很好的抽象类的例子,也是一个很不错的多态的例子):
#includeusing namespace std; class Shape { public: virtual double area() = 0; }; class Rectangle : public Shape { double m_a; double m_b; public: Rectangle(double a, double b) { m_a = a; m_b = b; } double area() { return m_a * m_b; } }; class Circle : public Shape { double m_r; public: Circle(double r) { m_r = r; } double area() { return 3.14 * m_r * m_r; } }; void area(Shape* s) { cout< area()<