把子类当成父对象使用(子类赋值给父类)

子类赋值给父类分三类分别是1-3
1.
子类对象赋值给父类对象父类对象=子类对象
2.
子类对象赋值给父类对象的引用&父类对象=子类对象
3.
子类对象的地址赋值给父类指针*父类对象=&子类对象
4.补充
5.总结
下面分别讲解:
1.赋值
   Drived d;
   Base b;
   b=d;
   把等号有右边的子类对象,赋值给等号左边的父类对象时,仅仅是把子类中来自于父类的那一部分成员,赋值给等号左边的父类对象,而赋值完成后,等号左边的对象,依然是父类的对象,依然是父类对象。(初始化父类,就是把两者公共的部分成员赋值给父类,左边的是父类还是父类)


2.引用赋值
   Derived d;
   Base &b=d;
   Derived::func();
   d.func();//错误
    b.func();//不能使用父类引用调用子类扩展成员
  把等号右边的子类对象,赋值给等号左边的父类的引用,直接初始化了父类的引用,虽然父类引用了子类对象,但该对象(b)调用该方法(子类继承父类的方法)还是父类的方法。如果不懂,下边有这方面的讲解。还有一点是:父类引用不能调用子类的所扩展的方法。例如:当b调用func()方法会出错,因为b是父类的引用,父类没有这个方法,会出错(尽管它引用了子类对象)。
3.指针赋值
Derived d;
Base *b=&d;
Drived::func(){};
d.func();//正确
b->func();//错误
  把等号右边的子类对象的地址,赋值给等号左边的父类的指针,直接初始化了父类的指针,这个和上边的引用类似,直接看例子,父类指针b指向了子类的对象,调用的时候,子类对象可以调用子类扩展的函数,而父类指针调用子类扩展的函数则会出错(原因还是因为父类地没有这个方法,尽管它的指针指向了子类对象)。
4.补充:
  当然如果你想通过父类访问子类扩展的也可以,那就必须强转了。
   Base * b=new Derived;
     Derived::func(){};
     //b->func(); error
    ((Deriverd*)b)->func();//ok, 强制转化
    如果父类指针指向子类对象,需要把父类的指针转化为指向子类对象的指针,来访问子类扩展成员这就是所谓的向下转。但是,向下转型是危险的,因为父类指针有可能没有指向子类对象。
总结:
1.左值必须是父类,否则会出现问题,无论它是什么类型的。(父类引用,指针)
2,将子类对象传递给父类的对象,引用或指针,而它的实际值是子类对象,
(例如:
     Base &func(Base & b)
            {
                  Derived*p=new Derived;
                  return*p;//返回值其实还是子类
            }
            Derivedd;
            Base&b=fun(d);
               Delete &b;   该函数的返回值是子类 )
3.子类对象转化为父类,向上转型(安全的)
4.父类转化为子类,向下转型(危险的)
原文地址:https://www.cnblogs.com/shuaigezhaoguang/p/5847254.html