當把一個派生類對象賦給一個基類對象時,會發生對象切割。(另外用基類對象強制轉換派生類對象也會)
對象切割會發生什麼呢?
#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_width=5;
m_height=4;
m_color=1;
}
~CRect(){};
double size()
{
return m_width*m_height;
}
virtual void draw()
{
cout<<"This is a rect!"<<endl;
cout<<m_color<<endl;
}
double m_width;
double m_height;
};
int main(int argc, char* argv[])
{
CShape shp;
CRect rect;
shp = rect;
shp.draw();
((CShape)rect).draw();//注意此行
CShape *pShape=new CShape();
*pShape=rect;//對象切割
pShape->draw();
pShape=▭//多态實作,
pShape->draw();
return 0;
}
shp=rect; 會調用 CShape的預設指派函數,shp的CShape屬性值與rect相同,但其虛函數表指針指向基類CShape虛函數表。
((CShape)rect).draw(); 會調用CShape預設的拷貝構造函數,生成一個中間變量,其虛函數表指針指向基類CShape虛函數表。
多态的實作是通過指針和引用;而對象的轉換隻會造成對象切割,不能實作多态。
注意下面兩句的不同
*pShape=rect;//對象切割
pShape=▭//多态
附基類和派生類對象間指派的問題:
class A
{
}
Class B:public A
{
}
A a_object;
B b_object;
有關
(1)a_boject=b_object;
(2)b_object=a_boject;
的說明。
==============
(1)aobject=bobject; 調用default A::operator =,由編譯器自動生成,它的函數聲明大緻類似于:A operator = (A rhs),反正=号右邊要求是一個A的對象,bobject作為A的子類對象亦是可行的,隻不過傳遞過程中會産生“截斷”。
(2)bobject=aobject; 調用default B::operator =,也由編譯器自動生成,它的函數聲明大緻類似于:B operator = (B rhs),這裡=号右邊要求是一個B的對象,aobject這時就不可行了。(編譯器将報錯)
這時,單單重載B::operator =也無濟于事,因為你無法改變operator = 函數參數必須是B對象的這個事實。要實作bobject=aobject;可以重載強制類型轉換函數,也可以利用編譯器隐式類型轉換的能力,如:
class A
{
public:
A(){}
};
class B:public A
{
public:
B(){}
B(A a){}//必須有
};
A aobject;
B bobject;
int main()
{
a_object=b_object;
b_object=a_object;
return 0;
}
--------------------------------------
Class 對象作參數時,用reference to const替換pass by value可避免對象切割。