在C++的继承中,类的继承分为三种,Public,Protected,Private。
Protected是Public和Private的混合,1在类的访问方面,Protected和Private一样,都是不能被类的用户访问,2在继承方面,像Public,protected成员可以被派生类成员访问。
基类中的函数有虚函数(vritual)和非虚函数。
对于非虚函数的调用,无论对象是什么类型,都执行基类类型所定义的函数,这是在编译时就确定的。如果调用虚函数,那么往往是在运行时确定的,这要涉及到动态绑定。
动态绑定要满足两个条件:
1:虚函数成员才能进行动态绑定。
2:必须通过基类类型的指针或者引用进行调用。
在动态绑定过程中,运行的虚函数是指针所指向的或引用所绑定的对象所属类型定义的版本。也就是调用实际对象类型中的虚函数。
下面看两个例子,这是在别人博客中看到的
例1:
#include<iostream>
using namespacestd;
class CA
{
public:
int i;
virtual void ff(){i=1;}
void print() {printf("%d\n",i);}
};
class CB:public CA
{
private:int i;
public:
virtual void ff(){i=2;}
void print(){printf("%d\n",i);}
};
class CC:public CB
{
private:
int i;
public:
virtual void ff(){i=3;}
void print(){printf("%d\n",i);}
};
int main()
{
CB*A=new CC();
A->ff();//因为ff()是虚函数,对象为CC,
//因此调用的是cc类的ff()
A->print();//调用的是CB类的print(),
//因为其基类为CB
//CB类中的i没有被赋值,下面两个对象输出结果原因同上
CC*B=(CC*)newCA();
B->ff();
B->print();
CC*C=(CC*)newCB();
C->ff();
C->print();
}
输出三个随机数。
| #include<iostream>
using namespacestd;
class CA
{
public:
int i;
virtual void ff(){i=1;}
virtual void print() {printf("%d\n",i);}
};
class CB:public CA
{
private:inti;
public:virtual void ff(){i=2;}
virtual void print(){printf("%d\n",i);}
};
class CC:public CB
{
private:int i;
public:
virtual void ff(){i=3;}
virtual void print(){printf("%d\n",i);}
};
int main()
{ CB*A=newCC();//构造的是CC对象
A->ff();//调用的是CC类中的ff()
A->print();//调用的是CC类中的print()
CC*B=(CC*)new CA();
B->ff();
B->print();
CC*C=(CC*)new CB();
C->ff();
C->print();
}
输出 3 1 2
| #include<iostream>
using namespacestd;
class CA
{
public:int i;
virtual void ff(){i=1;}
virtual void print() {printf("%d\n",i);}
};
class CB:public CA
{
private: int i;
public: virtual void ff(){i=2;}
};
class CC:public CB
{
private: int i;
public:
virtual void ff(){i=3;}
};
int main()
{
CB*A=newCC();
A->ff();
A->print();
CC*B=(CC*)newCA();
B->ff();
B->print();
CC*C=(CC*)newCB();
C->ff();
C->print();
}
输出:随机数 1 随机数.因为只有CA类中有print()函数,
只有构造的是CA类的对象时才会输出设定的值。
|
例2:
#include<iostream>
using namespace std;
class A
{
public:
virtual void fun1()
{
cout<<"A fun1"<<endl;
}
void fun2()
{
cout<<"A fun2"<<endl;
}
};
class B :public A
{
public:
void fun1()
{
cout<<"B fun1"<<endl;
}
void fun2()
{
cout<<"B fun2"<<endl;
}
};
int main()
{
B *obB=new B;
A *obA=obB;
obA->fun1(); //B fun1
obA->fun2(); //A fun2
cout<<endl;
obA = (B*)obA;
obA->fun1(); //B fun1
obA->fun2(); //A fun2
cout<<endl;
A *a1=new A;
B *b1=(B*)a1;
a1->fun1(); //A fun1
a1->fun2(); //A fun2
cout<<endl;
a1=(A*)a1;
a1->fun1(); //A fun2
a1->fun2();
cout<<endl; //A fun2
B b2;
A a2=b2;//对象类型进行了转换
a2.fun1();
a2.fun2();cout<<endl;
A a3;
// B b3=(B)a3; 不可以转换
return 0;
}
其中
A a2=b2;//对象类型进行了转换
是把派生类对象转换为基类对象了,注意这一点。