Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Inheritance 菱形继承中的虚拟类_Inheritance_Multiple Inheritance_Virtual Inheritance_Diamond Problem - Fatal编程技术网

Inheritance 菱形继承中的虚拟类

Inheritance 菱形继承中的虚拟类,inheritance,multiple-inheritance,virtual-inheritance,diamond-problem,Inheritance,Multiple Inheritance,Virtual Inheritance,Diamond Problem,根据我的理解,使用virtual会抑制基类的构造函数,因此能够避免实例化基类的多个对象 如果两个派生类的构造函数都被抑制,那么如何实例化基类(从中派生虚拟类)的一个实例 另外,如果基类的构造函数被抑制,当我有一个新类必须从其中一个虚拟类继承时,基类的构造函数也会被抑制吗 下面我用例子解释了我的问题 class student{ int rollNo; public : student(int a): rollNo(a) { } int getRollNo() {

根据我的理解,使用
virtual
会抑制基类的构造函数,因此能够避免实例化基类的多个对象

如果两个派生类的构造函数都被抑制,那么如何实例化基类(从中派生虚拟类)的一个实例

另外,如果基类的构造函数被抑制,当我有一个新类必须从其中一个虚拟类继承时,基类的构造函数也会被抑制吗

下面我用例子解释了我的问题

class student{ 
    int rollNo;
    public : student(int a): rollNo(a) { }
    int getRollNo() {
        return rollNo;
    }
};
class midsem : virtual public student{
    float midSemMarks;
    public : midsem(int a, float b) : student(a), midSemMarks(b) { }
    float getMidSemMarks() {
        return midSemMarks;
    }
};

class endsem : virtual public student{
    float endSemMarks;
    public : endsem(int a, float b):student(a),endSemMarks(b) { }
    float getEndSemMarks () {
        return endSemMarks;
    }
};
class total : public midsem, public endsem{
    float totalMarks;
    public:total(int a, float b, float c) :student(a), midsem(a,b), endsem(a,c) { }
    float getTotal() {
        return midsem::getMidSemMarks() + endsem::getEndSemMarks();
    }
  • 在上面的示例中,当创建
    total
    的对象时,将实例化
    student
    的单个对象。 但是,如果使用
    virtual
    endsem
    midsem
    中都压制了student的构造函数,那么在创建
    total
    对象时,如何创建
    student
    的一个实例

  • 现在,当我想创建另一个从
    endsem
    派生的类时,创建新类的对象会调用
    student
    类的构造函数吗,因为使用
    virtual
    应该会抑制它

  • 根据我的理解,使用虚拟会抑制 基类,因此能够避免 正在实例化的基类

    虚拟适用于继承关系;它抑制对任何中间派生类的虚拟基类构造函数的调用,无论该基类是否在ctor init列表中显式命名(在这种情况下,这意味着您将在没有该规则的情况下调用该基类的默认构造函数)

    如果两个派生类的构造函数都被抑制,那么 基类的一个实例(虚拟类从中 是否已(派生)实例化

    虚拟基类是从最派生的类初始化的,而不是从中间类初始化的,无论它们是否在类ctor init列表中明确提到

    通常,不提及基类意味着调用默认构造函数

    这意味着这些成员、构造函数必须可以作为非静态成员从最派生的类访问

    如果基类可以通过有效的可访问转换访问,则只能在派生类中访问非静态成员,因此:

    1) 虚拟基的私有继承可能导致代码格式错误:

    class PrivateBase {}; class Der : virtual PrivateBase {}; class Der2 : Der {}; 这个
    Der2bis
    变体几乎与
    Der2
    相似,只是虚拟基被再次继承,这几乎没有语义差异(某些数据结构的布局可能会改变),除了现在可以直接访问
    Der2bis
    的虚拟
    PrivateBase
    base之外,没有提供从类成员派生到基的
    Der2bis->PrivateBase
    转换的可访问性(从其他代码仍然无法访问转换)

    3) 这意味着只有当最派生的类成为基的朋友时,才能使用私有构造函数。这意味着某些类可以从派生,但没有有效的构造函数定义:

    class TheFriend;
    
    class AllPrivate {
      AllPrivate ();
      AllPrivate (AllPrivate&);
      friend class TheFriend;
    };
    
    class TheFriend : virtual AllPrivate { };
    
    请注意,
    TheFriend
    只能默认构造其基类子对象(通过命名其默认构造函数),因为它是它的朋友

    但进一步推导将失败,即使重复私人基础以使其可访问:

    class MoreDerived : TheFriend, virtual AllPrivate {};
    
    这里私有基是可访问的,但是它的成员仍然是不可访问的,
    MoreDerived
    不是朋友,它不能调用基构造函数,因此它的构造函数,无论是隐式还是显式定义的,都不能是格式良好的。

    没有“虚拟类”这样的东西;类可以在层次结构中显示为虚拟基类或非虚拟基类。(许多ppl使用虚拟函数调用类虚拟类,但这些类是多态类。)
    class MoreDerived : TheFriend, virtual AllPrivate {};