C ++ 17 инициализирует конструктор базового класса, используя константы управляемого класса в качестве параметров конструктора базового класса - PullRequest
0 голосов
/ 22 января 2020

Теперь, прежде чем продолжить, я хотел бы заявить, что я прочитал, что эти значения const должны быть инициализированы в списке инициализации конструктора. Однако в этом случае мне все еще нужны пояснения.

Вот очень простой пример наследования с прикрепленным кодом https://github.com/courteous/constrcutorChaining

класс F: E

класс E: D

класс D: C

класс C: B

класс B: A

Единственное spcecifi c Часть здесь состоит в том, что базовый класс «A» публично наследует от шаблона «enable_shared_from_this»

Теперь наблюдаются другие действия, которые я наблюдаю, т.е. когда я создаю указатель общего ресурса «E», тогда «параметризованный конструктор D называется: 17 "вызывается

shared_ptr<E> eInstance = make_shared<E>();

default A constructor called
default B constructor called
default C constructor called
parameterized D constructor called : 5
default E constructor called

, однако, если я создаю общий указатель класса F как этот

shared_ptr<F> fInstance = make_shared<F>();

default A constructor called
default B constructor called
default C constructor called
default D constructor called
default E constructor called
default F constructor called

, тогда конструктор E по умолчанию называется Почему это в этом случае.

Я нашел другие ответы в Stackoverflow, которые касаются проблемы, связанной с тем, что конструктор копирования не был реализован, т.е.

Вызывается конструктор по умолчанию вместо параметризованного конструктора

, но в этом случае не клонирование или копирование сделано то есть простой базовый конструктор явно называется.

Ожидаемое поведение здесь должно заключаться в том, что всегда должен вызываться параметризованный конструктор класса D, но это не тот случай, когда я создаю общий указатель на F. Может кто-нибудь сказать мне, почему и каков будет правильный подход? чтобы заставить класс F взять путь F-> "конструктор по умолчанию" E -> "конструктор по умолчанию" -> "параметризованный конструктор D с именем: 17".

В этом случае интересными классами являются F, E и D

Fh

#ifndef _F_
#define _F_

#include "E.h"

#include <string>
#include <memory>

namespace constructroTest
    {

    class F : public virtual E {


    public:
        static const uint16_t fixedLength;

        explicit F();
        virtual ~F();

protected:
        shared_ptr<F> shared_from_this()
            {
            return dynamic_pointer_cast<F>(E::shared_from_this());
            }
        };

    }


#endif  //#ifndef _F_

Eh

#ifndef _E_
#define _E_

#include "D.h"

#include <string>
#include <memory>

namespace constructroTest
    {

    class E : public virtual D
        {

    public:
        static const uint16_t fixedLength;

        explicit E();
        virtual ~E();

protected:
        shared_ptr<E> shared_from_this()
            {
            return dynamic_pointer_cast<E>(D::shared_from_this());
            }
        };

    }

#endif  //#ifndef _E_

Dh

#ifndef _D_
#define _D_

#include "C.h"
#include <string>
#include <memory>


namespace constructroTest
    {

    class D : public virtual C
        {


    public:
        static const uint16_t fixedLength;


        explicit D();
        virtual ~D();


        explicit D(uint16_t dArgument);


protected:
        shared_ptr<D> shared_from_this()
            {
            return dynamic_pointer_cast<D>(C::shared_from_this());
            }
        };

    }


#endif  //#ifndef _D_

1 Ответ

1 голос
/ 22 января 2020

В случае виртуального наследования только самый производный класс инициализирует виртуальный базовый класс.

Таким образом, в

shared_ptr<E> eInstance = make_shared<E>();

виртуальная база D создается из E

Принимая во внимание, что в

shared_ptr<F> eInstance = make_shared<F>();

виртуальная база D построена из F («игнорируя» E).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...