和QingLing讨论的IVIDA笔试题:
class FOO
{
public:
FOO(int j)
{
i=new int[j];
}
~FOO() {delete []i;}
private:
int *i;
};
class Bar:public FOO//必须是public继承,否则对象切割出错
{
public://构造函数必须是public,若要禁止实例化,则构造函数为private
//Bar(int j){ i2 = new int[j];}
Bar(int j):FOO(j){ i = new int[j];}//调用父类构造函数,初始化父类部分
~Bar() { delete [] i;}
private:
int *i;//可以和父类变量名相同,FOO::i
};
void main()
{
FOO *p = new FOO(100);
Bar *b = new Bar(200);
*p = *b; //默认赋值操作,对象切割,只是浅拷贝,内存泄露,析构出错
//FOO p(100);
//Bar b(200);
//p=b;
delete p;//重复析构
delete b;
}
对象切割 Object slicing
2008-12-23 18:22
#include <iostream> using namespace std; class CShape { public: CShape () { m_color=0; } ~CShape(){} virtual void draw() { cout<<"This is a shape!"<<endl; cout<<m_color<<endl; }
double m_color;
}; class CRect: public CShape { public: CRect() { m_color=1; } ~CRect(){}; virtual void draw() { cout<<"This is a rect!"<<endl; cout<<m_color<<endl; } double m_height;//加一个变量,清楚看清比基类大 }; int main(int argc, char* argv[]) { CShape shp; CRect rect; shp=rect; /* *下面这个shp.draw()的执行结果,你会觉得非常奇怪 * this is a shape * 1 * 你会很吃惊,竟然是1, *因为shp=rect; 会调用 CShape的默认赋值函数,shp的CShape属性值与rect相同,但其虚函数表指针指向基类CShape虚函数表。 *这就是大名顶顶的对象切割,要特别注意 */ shp.draw(); //((CShape)rect).draw();这个效果同上,发生对象分割
CShape *pShape=new CShape(); //*pShape=rect;这种写法也是对象分割 //而下面这种写法是正常的多态 /* 下面的输出结果为: this is rect 1 */ pShape=▭ pShape->draw(); return 0; }
|