首页 文章

三规则和继承

提问于
浏览
4

class A 定义了copy operator,析构函数和operator = . (Rule of Three

如果 B 继承自 A

  • 将自动调用析构函数

  • 我需要链接构造函数

  • operator= ...我应该为类 B 明确定义它吗?

5 回答

  • 6

    不,这是不必要的 .

    如果你仔细阅读“三规则”,你会注意到没有关于基类的说法,只能根据类的适当属性和行为做出决定 .

    (Check this example on ideone)

    #include <iostream>
    
    struct A {
      A(): a(0) {}
      A& operator=(A const& rhs) { a = rhs.a; return *this; }
      int a;
    };
    
    struct B: A { B(): b(0) {} int b; };
    
    int main() {
      B foo;
      foo.a = 1;
      foo.b = 2;
    
      B bar;
      bar = foo;
    
      std::cout << bar.a << " " << bar.b << "\n";
    }
    
    // Output: 1 2
    

    这实际上是 encapsulation 的真正力量 . 因为使用Rule of 3成功,在使基类的行为变得健全时,其派生类不需要知道复制构造函数是由编译器默认还是手动实现(并且复杂),这对用户来说都很重要(并且派生类是用户),是复制构造函数执行复制 .

    三条规则提醒我们一个实现细节,以帮助实现正确的语义 . 与所有实现细节一样,它仅对此类的实现者和维护者有用 .

  • 1

    Als说的是正确的,但我不确定他是否回答了你的问题 . 如果你想在B中做任何具体的事情,除了你在A三巨头中已经做过的事情之外,那么你也没有理由定义B的三巨头 .

    如果你确实需要其中一个,那么应该应用三个规则 .

  • 0

    这是一个示例代码和输出:

    #include <iostream>
    
    class A{
     int a;
     public:
     A():a(0){}
     A(A const & obj){std::cout << "CC called\n"; a = obj.a;}
     A & operator =(A & a){std::cout << "operator= called\n"; return a;}
     ~A(){std::cout << "A::dtor called\n";}
    };
    
    class B: public A{
    };
    
    int main(){ 
     B b,v;
     b=v;
    }
    

    输出:

    operator= called
    A::dtor called
    A::dtor called
    
  • 2

    同样的三个规则也适用于派生类 .
    该规则适用于所有类,您可以将它应用于继承层次结构中的每个类,就像将其应用于单个类一样 .

    如果 class B 需要 Big Three 的两个( Copy Constructor & Destructor )中的任何一个,那么您还需要定义复制赋值运算符 .

    因此,它实际上取决于Derived类的成员以及Derived类对象所需的行为 .

    例如:
    如果派生类成员由任何指针成员组成,并且您需要深层副本,那么根据Rule of 3,您的派生类需要重载并为三巨头提供自己的实现 .

  • 1

    将自动调用析构函数

    为了保持一致性,最好在派生类B中定义析构函数

    我需要链接构造函数

    当然 . 如果基本构造函数是默认值,那么它的一致性仍然更好 .

    operator = ...我应该为B类明确定义它吗?

    是的,像这样:

    struct A
    {
      A& operator=( const A & r )
      {
        // assign all A's member variables
        return *this;
      }
    };
    
    struct B : public A
    {
      B& operator=( const B & r )
      {
        A::operator=( r );
        // assign all B's member variables
        return *this;
      }
    };
    

相关问题