c++中使用基类指针Vector 存放子类对象(0xcccccccc 处未处理的异常: 0xC0000005: 读取位置 0xcccccccc 时发生访问冲突 )
2015-11-22 10:37
696 查看
1. c++中允许用基类指针指向子类的对象,先亮出正确写法。
#include <iostream> #include <vector> using namespace std; class Base { public: virtual void print(); }; class Derived : public Base { public: virtual void print(); }; void Base::print() { std::cout << "\n IN Base" << std::endl; } void Derived :: print() { std::cout << "\n IN derived" << std::endl; } int main() { vector<Base*> baseclass; Base* ptrDerived = new Derived; baseclass.push_back(ptrDerived); Base* ptrBase = new Base; baseclass.push_back(ptrBase); baseclass.push_back(new Derived); vector<Base*>::const_iterator iter; for(iter = baseclass.begin(); iter != baseclass.end(); ++iter) { (*iter)->print(); } system("pause"); return 0; }
这种写法中print()是可以多态的虚函数,由不同的指针决定了访问基类的print();还是子类的print();
2. 但是如果创建基类Vector后直接将子类对象放到其中会发生截断。
vector<Base> baseclass; Derived temp1= new Derived; baseclass.push_back(temp1); Base temp2 = new Base; baseclass.push_back(temp2); baseclass.push_back(new Derived);
这种情况下vector baseclass中的三个元素全部会截断为基类对象
3. 使用指针vector容易出错的地方 0xcccccccc 处未处理的异常: 0xC0000005: 读取位置 0xcccccccc 时发生访问冲突
//正确写法
vector<Base*> baseclass; Base* ptrDerived = new Derived; baseclass.push_back(ptrDerived); Base* ptrBase = new Base; baseclass.push_back(ptrBase); baseclass.push_back(new Derived);
//危险写法
//类成员 public
vector<Base*> baseclass;
//以下在某函数中 Derived temp1; // 这里对象不是new出来的 而是自己定义的 baseclass.push_back(&temp1); Base temp2; baseclass.push_back(&temp2);
因为vector所做的是值拷贝,这种情况下它只会把temp1 temp2两个对象的指针拷贝到baseclass中,如果temp1和temp2是在某个函数中定义的,这样函数执行后对象由于不是new出来的会被系统自动回收。
这样vector中的指针就是野指针,再访问就会出错。
**解决方案 遇到这种情况一定要检查放到指针vector的对象是不是new出来的。
4. 关于如何取出vector<Base *>中的子对象指针
方法一:使用多态 动态联编的方法 比如 (*iter)->print();
方法二:强制类型转换,在你知道要强制转换成什么对象的时候。这种方法是静态编译的。
(Deirved*)baseclass[0]
还是推荐第一种,比较高端。
相关文章推荐
- 26.c/c++程序员面试宝典-访问控制
- 关于有符号数和无符号数的转换 - C/C++
- C语言的32个关键字、9种控制语句、34个运算符
- C/C++中static关键字详解
- C++11 你真的会用迭代器(iterator)么?
- C++内存管理技术内幕
- Mac终端编译运行C++
- 单向链表 (Singly linked list) 的C++实现
- C语言学习 数独游戏
- 图的深度优先和广度优先遍历(图以邻接表表示,由C++面向对象实现)
- C++解引用运算符*重载
- C++解引用运算符*重载
- Effective C++ 笔记 第五部分 实现
- 89C51与ad0832 输出正弦波,三角波,矩形波,锯齿波
- C++设计模式——桥接模式
- 010--VS2013 C++ 平面地图贴图
- 009--VS2013 C++ 显示位图部分透明化
- hdu 1000 1001
- C++ 可变参函数实现
- 008--VS2013 C++ 位图半透明化(另一种显示)