1,纯虚函数
(1)定义方式:在虚函数的形参表后用“=0”声明,例如:
class Base4
{
public:
Base4(int ii, int jj) :i(ii), j(jj) { cout << "调用基类的一般构造函数" << endl; }//基类的一般构造函数
Base4() :i(0), j(5203132){cout << "调用基类的默认构造函数" << endl;} //基类的默认构造函数
Base4(const Base4& b4);//复制构造函数
Base4& operator=(const Base4& b4);
virtual ~Base4() { cout << "调用基类的析构函数" << endl; }
void show_base() { cout << i << "\t" << j<<"\t"; }
virtual void hello() = 0;//纯虚函数
public:
int i;
private:
int j;
};
其中的hello就是纯虚函数。
(2)含有一个或多个纯虚函数的类为
抽象基类。抽象基类只能用来继承,
不能用来创建对象。
(3)如果派生类没有定义所继承的纯虚函数的自身版本,则派生类也是抽象类。
2,容器与继承
当我们将派生类对象赋值给基类对象的容器时,容器里装的依然是
基类对象,派生类部分被切掉了。能访问的也仅仅是继承得来的基类的成员。
class Base4
{
public:
Base4(int ii, int jj) :i(ii), j(jj) { cout << "调用基类的一般构造函数" << endl; }//基类的一般构造函数
Base4() :i(0), j(5203132){cout << "调用基类的默认构造函数" << endl;} //基类的默认构造函数
Base4(const Base4& b4);//复制构造函数
Base4& operator=(const Base4& b4);
virtual ~Base4() { cout << "调用基类的析构函数" << endl; }
void show_base() { cout << i << "\t" << j<<"\t"; }
virtual void hello() = 0;//纯虚函数
public:
int i;
private:
int j;
};
class D4 :public Base4
{
public:
D4() :k(0) { cout << "调用派生类的默认构造函数" << endl;}//派生类的默认构造函数
D4(int ii, int jj, int kk) :Base4(ii, jj), k(kk) //派生类的一般构造函数
{cout << "调用派生类的一般构造函数" << endl;}
D4(int kk) : k(kk) {}//派生类的一般构造函数,隐式调用基类的默认构造函数
D4(const D4& d4);//派生类的复制构造函数
D4& operator=(const D4&);
~D4() { cout << "调用派生类的析构函数" << endl; }
virtual void hello() { cout << "hello 派生类" << endl; }
int k;
void show_d() { show_base(); cout << k << endl; }
};
int main()
{
D4 d1(520, 3132, 1314);
vector<Base4> vB;
cout << "push_back:" << endl;
vB.push_back(d1);
vB[0].show_base();
//vB[0].show_d();//error C2039: “show_d”: 不是“Base4”的成员
}
如果我们试图使用语句“vB[0].show_d();”来使用派生类新增的成员,就会编译出错。因为容器里装的永远都是基类,派生类部分被剪掉了。
试想:如果派生类使用private或protected继承会怎么样??
此时派生类对象无法获得基类成员的访问权限,将其放入容器会怎样呢?
我们将D4的继承方式改为private:
class D4 :private Base4
{
public:
D4() :k(0) { cout << "调用派生类的默认构造函数" << endl;}//派生类的默认构造函数
D4(int ii, int jj, int kk) :Base4(ii, jj), k(kk) //派生类的一般构造函数
{cout << "调用派生类的一般构造函数" << endl;}
D4(int kk) : k(kk) {}//派生类的一般构造函数,隐式调用基类的默认构造函数
D4(const D4& d4);//派生类的复制构造函数
D4& operator=(const D4&);
~D4() { cout << "调用派生类的析构函数" << endl; }
virtual void hello() { cout << "hello 派生类" << endl; }
int k;
void show_d() { show_base(); cout << k << endl; }
};
其他代码不变,执行编译:
error C2243: “类型转换”: 从“D4 *”到“const Base4 &”的转换存在,但无法访问。
使用protected继承的效果一样。
所以,
如果不是public继承,就根本不能将派生类放到基类的容器中去。