繁体   English   中英

C ++中的对象切片

[英]Object Slicing in c++

    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. 如何避免对象切片。

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

但是,你只能直接通过指针-TO-访问基地声明成员变量(或函数) Base 这就是为什么varBase->iDerived无法编译的原因。

切片通常涉及以下内容:

Derived d;
Base b = (Base)d;

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

这些东西是相对基本的。 我建议选择一本不错的C ++书。 这里有一个不错的清单: The Definitive C ++ Book Guide和List

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; }
};

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM