Алмазная проблема |Параметризованный конструктор не вызывается из класса прародителя. - PullRequest
0 голосов
/ 17 сентября 2018

Может кто-нибудь объяснить, пожалуйста, множественное наследование ниже, почему конструктор параметризации класса d не вызывается, даже если класс транспортного средства создается с помощью конструктора параметризации.

#include<iostream>

using namespace std;

class d{
    public:
    d()
    {
        cout<<"in default constructor of d"<<endl;
    }
    d(int x)
    {
        cout<<"in parametrized constructor of d"<<endl;
    }
    void a()
    {
        cout<<"a function of d";
    }
};
class Vehical:virtual public d
{
    public:
    Vehical(int x):d(x)
    {
     cout<<"In paramterized constructor of Vehical"  <<endl;
    }
    void a()
    {
        cout <<"a function of Vehical class"<<endl;
    }
    Vehical()
    {
     cout<<"default constructor of Vehical"<<endl;   
    }
};
class now: virtual  public d
{
public:
void a()
{
    cout <<"a function of now "<<endl;
}
    now()
{
  cout<<"Default constructor of now" <<endl; 
}
};
class car :public  Vehical, public now
{
    public:
    car();
    car(int y):Vehical(y)
    {

    };
     //using d::a;
       using Vehical::a;

};
int main()
{
 car ob(1);
  ob.a();
 return 0;
}

Вывод:

in default constructor of d
In paramterized constructor of Vehical
Default constructor of now

Ожидание: он должен был вызывать paremterized-конструктор D вместо default, так как мы конструировали транспортное средство, передавая параметр, который действительно вызывает paramterized-конструкторКласс D.

Также, если мы удалим виртуальный из одного класса, у нас снова будет проблема с алмазом?почему так?

Сценарий 1): если мы удалим виртуальный из класса транспортного средства, у нас будет следующий вывод

in default constructor of d
in parametrized constructor of d
In paramterized constructor of Vehical
Default constructor of now
a function of Vehical class

Также в приведенном выше выводе почему сначала вызывается конструктор по умолчанию, а затем параметризация dclass? Также в выходных данных, почему сначала вызывается и конструктор d, а затем транспортное средство, а теперь и конструктор класса.

Ожидание: он должен был вызвать сначала параметризованный конструктор d, а затем параметризовать конструктор транспортного средства, а затем конструктор по умолчанию для d, а затемконструктор по умолчанию сейчас

Сценарий 2) А теперь мы удалим виртуальный класс from now и теперь у нас есть вывод, в котором конструктор по умолчанию d вызывается вместо paramterize?

in default constructor of d
In paramterized constructor of Vehical
in default constructor of d
Default constructor of now
a function of Vehical class

Ожидание: для первой строки он должен был вызвать параметризованный конструктор D вместо стандартного.

1 Ответ

0 голосов
/ 17 сентября 2018

В Страшном Алмазе Смерти есть две проблемы:

1.Надежность базового класса - какой базовый класс должен быть выбран при обращении к этому классу «дедушки».

2. Какой конструктор класса дедушки использует при явном вызове конструкторов базовых классов. Представьте себе следующий пример:

class foo{
    public:
    foo() { }
    foo(int x) {  }
};
class bar : virtual public foo
{
    public:
    using foo::foo;
};
class baz: virtual  public foo
{
public:
    using foo::foo;
};
class clazz :public  bar, public baz
{
public:
    clazz(int i) : bar(i), baz(i+1){}
};

Какой конструктор foo должен выбрать компилятор, так как должен быть создан только один дед? Что ж, любой выбор будет означать разрешение конфликта между конфликтующими вызовами конструктора foo (под конфликтом я подразумеваю разные аргументы). Выбор дизайна языка в C ++ - не пытайтесь разрешить конкуренцию, просто возложите ответственность за инициализацию дедушкиного класса на программистов. Это имеет смысл, потому что наследование алмазов является ключевым случаем, для которого может потребоваться особый способ инициализации.

Вы должны явно вызвать конструктор d в конструкторе класса внука:

#include<iostream>

using namespace std;

class d{
    public:
    d()
    {
        cout<<"in default constructor of d"<<endl;
    }
    d(int x)
    {
        cout<<"in parametrized constructor of d"<<endl;
    }
    void a()
    {
        cout<<"a function of d";
    }
};
class Vehical:virtual public d
{
    public:
    Vehical(int x):d(x)
    {
     cout<<"In paramterized constructor of Vehical"  <<endl;
    }
    void a()
    {
        cout <<"a function of Vehical class"<<endl;
    }
    Vehical()
    {
     cout<<"default constructor of Vehical"<<endl;   
    }
};
class now: virtual  public d
{
public:
void a()
{
    cout <<"a function of now "<<endl;
}
    now()
{
  cout<<"Default constructor of now" <<endl; 
}
};
class car :public  Vehical, public now
{
    public:
    car();
    car(int y):Vehical(y), d(y)
    {

    };
     //using d::a;
       using Vehical::a;

};
int main()
{
 car ob(1);
  ob.a();
 return 0;
}
...