C++学习笔记53——纯虚函数与继承中的容器
2016-03-03 22:00
525 查看
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继承,就根本不能将派生类放到基类的容器中去。
相关文章推荐
- C++程序员如何向一个java工程师解释何为reference引用?
- Problem D、F: C语言习题 矩阵元素变换
- C++程序员如何向一个java工程师解释何为reference引用?
- c++ 函数的隐藏和覆盖
- Problem C: C语言习题 整数排序
- C++类的声明与实现中容易忽视的重定义默认参数的错误
- c++ 基类已经存在virtual修饰的同名成员函数,派生类加不加无所谓,都是virtual的
- 【C/C++学院】0907-象棋五子棋代码分析/寻找算法以及排序算法
- 奇怪的c语言
- C语言SOCKET编程指南
- 《Effective C++ 》学习笔记——条款11
- 【C++学习之路】派生类的构造函数(二)
- C++的初始化与清除(补充1)
- DSP 2812: 使用C++封装定时器及应用举例
- 【C++】 单链表 .cpp
- 1095. Cars on Campus (30)
- DSP 2812: 使用C++封装中断控制器PIE
- C指针作为函数参数引用
- c++中strtok的用法,杭电2072
- string类(c++)