多态
1.多态性是面对对象程序设计的重要特征之一。
2.多态性是指发出同样的消息被不同类型的对象接收时可能导致完全不同的行为。
3.多态的实现:
3.1函数重载
3.2运算符重载
3.3模板
3.4虚函数
静态绑定与动态绑定
1.静态绑定
绑定过程出现在编译阶段,在编译期就已经确定要调用的函数。
2.动态绑定
绑定过程工作在程序运行时执行,在程序运行时才确定将要调用的函数。
虚函数
1.虚函数概念:在基类中冠以关键字virtual的成员函数
2.虚函数的定义:
2.1virtual 函数类型 函数名称(参数列表);
2.2如果一个函数在基类中被声明为虚函数,则它在所有派生类中都是虚函数。
3.只有通过基类指针或引用调用虚函数才能引发动态绑定
4.虚函数不能声明为静态。
#include <iostream>
using namespace std;
class Base
{
public:
virtual void Fun1()
{
cout << "Base::Fun1..." << endl;
}
virtual void Fun2()
{
cout << "Base::Fun2..." << endl;
}
void Fun3()
{
cout << "Base::Fun3..." << endl;
}
};
class Derived : public Base
{
public:
virtual void Fun1()
{
cout << "Derived::Fun1..." << endl;
}
virtual void Fun2()
{
cout << "Derived::Fun2..." << endl;
}
void Fun3()
{
cout << "Derived::Fun3..." << endl;
}
};
int main()
{
Base* p;
Derived d;
p = &d;
p->Fun1();
p->Fun2();
p->Fun3();
return 0;
}
运行结果:
虚析构函数
1.何时需要虚析构函数?
当你可能通过基类指针删除派生类对象时
如果你打算允许其他人通过基类指针调用对象的析构函数(通过delete这样做是正常的),并且被析构函数的对象有重要的析构函数的派生类的对像,就需要让基类的析构函数作为虚函数。
#include <iostream>
using namespace std;
class Base
{
public:
Base()
{
cout << "Base..." << endl;
}
virtual void Fun1()
{
cout << "Base::Fun1..." << endl;
}
virtual void Fun2()
{
cout << "Base::Fun2..." << endl;
}
void Fun3()
{
cout << "Base::Fun3..." << endl;
}
virtual ~Base() // xxxxxx
{
cout << "~Base..." << endl;
}
};
class Derived : public Base
{
public:
Derived()
{
cout << "Derived..." << endl;
}
virtual void Fun1()
{
cout << "Derived::Fun1..." << endl;
}
virtual void Fun2()
{
cout << "Derived::Fun2..." << endl;
}
void Fun3()
{
cout << "Derived::Fun3..." << endl;
}
~Derived()
{
cout << "~Derived..." << endl;
}
};
int main()
{
Base* p = new Derived;
p->Fun1();
delete p;
return 0;
}
虚表指针
1.虚函数的动态绑定是通过虚表来实现的。
2.包含虚函数的类头4个字节存放指向虚表的指针。
基类
#include <iostream>
using namespace std;
class Base
{
public:
virtual void Fun1()
{
cout << "Base::Fun1..." << endl;
}
virtual void Fun2()
{
cout << "Base::Fun2..." << endl;
}
int data1_;
};
class Derived : public Base
{
public:
virtual void Fun2()
{
cout << "Derived::Fun2..." << endl;
}
int data2_;
};
typedef void(*FUNC)();
int main()
{
cout << sizeof(Base) << endl;
cout << sizeof(Derived) << endl;
Base b;
long** p = (long**)&b;
FUNC fun = (FUNC)p[0][0];
fun();
fun = (FUNC)p[0][1];
fun();
return 0;
}
派生类
#include <iostream>
using namespace std;
class Base
{
public:
virtual void Fun1()
{
cout << "Base::Fun1..." << endl;
}
virtual void Fun2()
{
cout << "Base::Fun2..." << endl;
}
int data1_;
};
class Derived : public Base
{
public:
virtual void Fun2()
{
cout << "Derived::Fun2..." << endl;
}
virtual void Fun3()
{
cout << "Derived::Fun3..." << endl;
}
int data2_;
};
typedef void(*FUNC)();
int main()
{
cout << sizeof(Base) << endl;
cout << sizeof(Derived) << endl;
cout << "演示基类..." << endl;
cout << endl;
Base b;
long** p = (long**)&b;
FUNC fun = (FUNC)p[0][0];
fun();
fun = (FUNC)p[0][1];
fun();
cout << endl;
cout << "演示派生类..." << endl;
cout << endl;
Derived d;
p = (long**)&d;
fun = (FUNC)p[0][0];
fun();
fun = (FUNC)p[0][1];
fun();
fun = (FUNC)p[0][2];
fun();
cout << endl;
cout << "演示动态绑定..." << endl;
cout << endl;
Base* pp;
pp = &d;
pp->Fun2();
return 0;
}
object slicing与虚函数
没听懂
overload、override、overwrite
1.成员函数被重载的特征:
1.1相同的范围(在同一个类中)
1.2函数名字相同
1.3参数不同
1.4virtual关键字可有可无
2.覆盖是指派生类函数覆盖基类函数,特征是:
2.1不同的范围(分别位于派生类与基类);
2.2函数名字相同;
2.3参数相同;
2.4基类函数必须有virtual关键字。
3.重定义(派生类与基类)
3.1不同的范围(分别位于派生类与基类);
3.2函数名字与参数都相同,无virtual关键字;
3.3函数名字相同,参数不同,virtual关键字可有可无