用c ++中的对象切片

时间:2011-01-24 08:45:16

标签: c++ inheritance object-slicing

    class Base
    {  
         int iBase;

      public:           
         virtual void display()
         {
            cout<<"I am a Base Class"<<endl;
         }        
    };

    class Derived : public Base
    { 
        int iDerived;

     public:
        Derived()
        {
            cout<<"In Derived Default Constructor"<<endl;
            iDerived=10;
        }   

        void display()
        {
            cout<<"I am in Derived Class"<<endl;
            cout<<"value of iDerived  :"<<iDerived<<endl;
            iDerived=100;
            cout<<"value of iDerived  :"<<iDerived<<endl;
        }                
   };

在MAIN:

     Base *varBase;
     Derived varDerived;

     varBase = &varDerived;
     varBase->display();
     varBase->iDerived=10; // Error: iDerived is not a member of Base: ?????

大家好,

我正在尝试理解对象切片并尝试一些 示例程序。

我用指针参考Objcet切片读到的地方不会 发生。

但是在下面的示例中,我注意到iDerived无法访问Base pointer(varBase),但是我可以访问virtual display method of class,即使它不在显示方法的本地范围内。

现在我的问题是:

  1. 为什么我只能使用虚函数访问iDerived变量,这是正确的吗?
  2. 如何避免对象切片。

2 个答案:

答案 0 :(得分:2)

您的示例代码根本不涉及切片。您所做的就是调用基本多态。通过将Base::display()声明为virtual并在display()上调用Base *,您已要求它动态调用实际类型中的成员函数被指向的对象,DerivedDerived的成员变量在Derived::display()的范围内,因此这就是编译和工作的原因。

但是,您只能通过指向Base的指针直接访问 Base 中声明的成员变量(或函数)。这就是varBase->iDerived无法编译的原因。

切片通常涉及以下内容:

Derived d;
Base b = (Base)d;

通过明确分配/初始化Base对象,所有Derived特定成员都将丢失(即它们已被“切掉”)。

这个东西比较基本;我建议你拿一本关于C ++的好书。这里有一个很好的列表:The Definitive C++ Book Guide and List

答案 1 :(得分:0)

C ++具有虚拟功能,但没有虚拟数据。

您可以添加以下内容来模拟它:

class Base {
  // What you had before
  virtual int getAnInt() const = 0; // =0 means that Derived must implement this
};
class Derived {
  // What you had before
  virtual int getAnInt() const { return iDerived; }
};

对象切片完全不相关,在您的示例中不会发生。