先看一段代码
#include <iostream>
using namespace std;class A
{
public:
A()
{
cout << 1;
dosomething();
}
virtual void dosomething()
{
cout << "I am A";
}
};
class B :public A
{
public:
B(int x) :A()
{
cout << x;
}
virtual void dosomething()
{
cout << "I am B";
}
};
int main()
{
B b(3);
system("pause");
return 0;
}
输出结果为 1 I am A 3
分析:B继承于A ;B b调用自身默认构造函数时,先调用A的构造函数,因此输出1,在A的构造函数中调用dosomething时,this指针是指向自身的函数,因此输出I am A。最后调用自身的构造函数,输出3;
再看第二个例子:
#include <iostream>
using namespace std;
class Base
{
public:
virtual void print(int a)
{
cout << "Base print int" << a << endl;
}
virtual void print(char a)
{
cout << "Base print char" << a << endl;
}
virtual void print(double a)
{
cout << "Base print double" << a << endl;
}
};
class Derived :public Base
{
public:
void print(int a)
{
cout << "Derived print int " << a << endl;
}
};
int main()
{
Derived d;
d.print(10);
d.print(5.88);
d.print('d');
system("pause");
return 0;
}
输出将结果为:Derived print int 10
Derived print int 5
Derived print int 100
这种情况是继承中 的名字隐藏问题。当父类中有一组重载函数,子类在继承父类时如果覆盖了这组重载函数中的任意一个,则其余没有被覆盖的同名函数在子类中是不可见的。因此,父类中的方法子类无法访问。当父类与子类中,没有同时使用virtual修饰时,会根据引用或者指针 自身的类型选择方法。
当子类中声明如下时:
virtual void print(int a)
{
cout << "Derived print int " << a << endl;
}
virtual void print(double a)
{
cout << "Derived print int " << a << endl;
}
如果用父类指针 指向子类对象 调用print方法时,会根据参数进行最佳匹配。
面向对象三大特性:封装、继承、多态。多态是指,方法(函数)的调用结果取决于调用者。
实现方法:1.在派生类中重新定义基类的方法
例子见上
2.使用虚方法(在方法前 加上virtual关键字)
原理:当类中含有虚函数时,每声明一个对象,则对象中保存了一个指向虚函数表的指针,vptr指针,虚函数表中保存了虚函数的地址。派生类对象将包含一个指向独立地址表(它自身的虚函数表)的指针。用父类指针指向不同的子类对象时,将获取子类对象中vptr指针的值,调用其指向的虚函数表中的函数。