代码之家  ›  专栏  ›  技术社区  ›  BarsMonster

C++类:派生类和虚方法[复制]

  •  1
  • BarsMonster  · 技术社区  · 14 年前

    可能的重复:
    C++ : implications of making a method virtual
    Why is 'virtual' optional for overridden methods in derived classes?

    我想知道,在以下情况下,记录的行为是什么:

    你有

    class A
    {
     virtual void A()
     {
       cout << "Virtual A"<<endl;
     }
     void test_A()
     {
       A();
     }
    }
    
    class B: public A
    {
      void A()
      {
       cout << "Non-virtual A in derived class"<<endl;
      }
    
      void test_B()
      {
        A();
      }
    }
    
    A a; B b;
    a.test_A();
    b.test_A();
    b.test_B();
    

    按照C++标准应该做什么?为什么? GCC的工作方式类似于B::A也是虚拟的。

    当派生类中的非虚拟方法重写虚拟方法时,通常应该发生什么情况?

    4 回复  |  直到 7 年前
        1
  •  3
  •   Björn Pollex    14 年前

    如果存在具有相同名称和签名的虚拟基类成员函数,则子类成员函数隐式虚拟化。

        2
  •  2
  •   David Rodríguez - dribeas    14 年前

    代码不应该编译,因为不能用类的名称命名方法。但关于我的理解这是你真正的问题:

    使一个方法成为虚的意味着所有派生类中的同一个方法都是虚的,即使 virtual 关键字不存在?

    答案是肯定的。一旦一个方法在类中声明为虚的,那么该方法的所有重写都将是虚的,并且 事实上的 关键字在派生类中是可选的(即使我建议键入它,如果仅用于文档目的)。注意,要使派生类中的方法成为重写,它必须具有相同的名称和签名,唯一的潜在差异是协变返回类型:

    struct A {};
    struct B : A {};
    struct base {
       virtual A* foo();
       virtual A* bar();
    };
    struct derived : base {
       virtual B* foo();    // override, covariant return type
       virtual int bar();   // not override, return type is not covariant
       virtual A* bar(int); // not override, different argument list
    };
    
        3
  •  0
  •   Chubsdad    14 年前

    此代码格式错误。构造函数不能有返回类型(就像对“A”的构造函数所做的那样)。构造函数也不能是虚拟的。

    在修复了一个构造函数之后,B类的形状不正确,它是一个私有的构造函数。

    因此,这段代码有很多问题(包括类定义中缺少分号)。

        4
  •  0
  •   Chubsdad    14 年前

    按照标准应该是

    A a; B b;
    a.test_A();  //"Virtual A"
    b.test_A(); //Non-virtual A in derived class
    b.test_B(); //Non-virtual A in derived class