C++ 在C+中,将基类赋值给派生类,反之亦然+;以及静态对象和动态对象之间的区别

C++ 在C+中,将基类赋值给派生类,反之亦然+;以及静态对象和动态对象之间的区别,c++,oop,downcast,upcasting,C++,Oop,Downcast,Upcasting,考虑到 class base { } 及 这两者之间的区别是什么: 第一种情况: int main() { base b; derived d; } int main() { base *b; derived *d; } 及 第二种情况: int main() { base b; derived d; } int main() { base *b; derived *d; } 如果我们在第二种情况下向下和向上都是这样: // upcast - imp

考虑到

class base { }

这两者之间的区别是什么:

第一种情况:

int main() {
  base b;
  derived d;
}
int main() {
  base *b;
  derived *d;
}

第二种情况:

int main() {
  base b;
  derived d;
}
int main() {
  base *b;
  derived *d;
}
如果我们在第二种情况下向下和向上都是这样:

  // upcast - implicit type cast allowed
  Base *b= &d; 

  // downcast - explicit type case required 
  Derived *d=  (Dervied *) &b;

在第一种情况下,我们如何才能做到这一点呢?

这个答案的一部分是从

指针和引用允许后期绑定/运行时多态性,而对象将导致对象切片(请参见@François Andrieux注释)

这种对象切片的结果是什么:如果直接使用对象,即使使用虚拟方法,也会丢失信息并可能调用错误的方法

以下是一个例子:

#include <iostream>
using namespace std;

class A
   {
      public : virtual  void print(void)
           {
              cout<< "A::print()"<<endl;
           }
    };
 class B : public A
    {
      public : virtual void print(void)
           {
               cout<<"B::print()"<<endl;
           }
    };

int main(void)
{
    A a;
    B b;
    A& ref = b;

    a=b;
    a.print();
    ref.print();
    return 0;
}
#包括
使用名称空间std;
甲级
{
公共:虚拟作废打印(作废)
{

在第二种情况下,CuTuy不需要任何代码>和<代码>操作符。在第一种情况下,将<代码> d <代码>分配给<代码> b <代码>将导致和分配从<代码> b>代码>到<代码> d>代码>没有意义。自从2年以来,就没有使用C++,试图刷新我的记忆。第二种情况,在第一种情况下,你怎么做?(一些朋友告诉我我们需要重载=运算符?)你不能使用值语义(第一种情况)。一个
base
永远不能表示一个
派生的
(可能是针对为它专门设计的
base
的有限情况).只有
base
指针或引用可以引用
派生的
。因此我们需要制作一个复制构造函数?这个问题实际上在硕士学位入学考试中有说明。问题是,考虑到base和派生的静态对象,你能对赋值d=b说些什么,可能的答案是:1.不可能,2.可以使用向下转换d=(派生)b来完成,3.可以通过重载=运算符来完成。由于可以重载=运算符,当然可以将其实现为
Derived::Derived operator=(Base obj)
并使语句
d=b
有效并编译。
d=(派生)b
仅当存在构造函数时才应编译
派生::派生(基本obj)
。使赋值
d=b
编译绝非不可能。