【问题标题】:C++ assignment operators question about inheritanceC++ 赋值运算符关于继承的问题
【发布时间】:2011-08-12 19:00:29
【问题描述】:

我有两个类——基类 A 和派生类 B——我写了这个

A obj;  
B obj2;  
obj = obj2;  

如果我还没有覆盖任何赋值运算符,实际会发生什么?这是否只是将 obj2 的 A 部分复制到 obj 中?这是正确的,还是编译器只是原谅的错误? IS_A 关系是否允许执行此语句?任何帮助是极大的赞赏。

【问题讨论】:

标签: c++ inheritance assignment-operator


【解决方案1】:

重载你的赋值运算符。并且在实现 B 部分中,A 部分中的 thts 将被分配...在您尝试分配 A 中存在的 B 值之前不会生成编译器错误

【讨论】:

    【解决方案2】:

    这当然是允许的。它会将obj2A 子对象分配给obj

    由于 IS-A 关系,几乎不可能在编译时阻止这种情况,而不防止从 A 的实例分配。

    【讨论】:

    • 如果继承是Private是不允许的。
    • @Als:我认为这是为了公共继承。
    • 没问题!为了清楚起见,我认为它很容易明确提及。
    【解决方案3】:

    它会浅拷贝 obj2 的“A”部分。

    从语言的角度来说完全没问题。

    如果它适合您的应用程序,这取决于许多因素,但这就是您可以重载赋值运算符的原因。

    【讨论】:

      【解决方案4】:
      class Base
      {
          //Members       
      };
      
      class Derived1:public Base
      {
          //Members
      };
      
      class Derived2:private Base
      {
          //Members 
      };
      
      
      int main()
      {
          Base obj1;
          Derived1 obj2;
          Derived2 obj3;
      
          obj1 = obj2;   //Allowed Since Public Inheritance 
          obj1 = obj3;   //Not Allowed, Compiler generates error
      }
      

      obj1 = obj2 只有那些从基类继承的派生类 obj2 的成员被复制到 obj1 中时,派生类的其余成员被切掉。这仅仅是因为基类 obj1 不知道派生类的成员。这个现象被称为Object Slicing

      如果类有指针成员变量需要在堆上分配,那么obj1 = obj2创建一个Shallow Copy,这意味着obj1和obj2内部的指针成员变量现在将指向同一个堆内存。那么如果 obj2 被操作系统回收并且 obj1 仍在使用中会发生什么?灾难!因此,overloading = operator 应避免浅拷贝,并制作 Deep copy 对象。

      【讨论】:

        【解决方案5】:
        A::operator=(const A& value);
        

        将被执行。 obj1 隐式转换 (static_cast) 为 const A&

        所以你的obj=obj1; 相当于

        obj = static_cast<const A&>(obj1);
        

        显然隐式生成的赋值将分配A 的每个非静态成员。

        要拒绝这一点,请使用私有/受保护的继承。通过使用公共继承,您声称所有 B 类型的对象都可以以各种可能的方式合法地用作 A 类型的对象。

        你也可以显式声明

        A& A::operator=( const B& value );
        

        或者你也可以定义

        A& A::operator=( const A& value );
        

        以多态方式表现。

        【讨论】:

          猜你喜欢
          • 2021-06-07
          • 2015-02-09
          • 2012-02-28
          • 1970-01-01
          • 2020-12-15
          • 2018-11-24
          • 2021-08-28
          • 1970-01-01
          • 2011-04-22
          相关资源
          最近更新 更多