C++17 使用派生的 class 常量作为基 class 构造函数的参数初始化基 class 构造函数

C++17 initializing base class constructor using drived class constants as the paramers of the base class constructor

现在,在我继续回答这个问题之前,我想声明我已经阅读了 const 值,必须在构造函数的初始化列表中初始化引用。但是在这种情况下我仍然需要澄清。

这是一个非常简单的继承示例,附有代码https://github.com/courteous/constrcutorChaining

class F : E

class E : D

class D : C

class C : B

class乙:甲

这里唯一的特殊部分是基础 class "A" 从模板 "enable_shared_from_this"

公开继承

现在我观察到的不同行为是,当我创建 "E" 的共享指针时,"parameterized D constructor called : 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

但是如果我像那样创建 class 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 构造函数 为什么在这种情况下会这样。

我在 Whosebug 中找到了其他答案,这些答案涉及复制构造函数未被实现的问题,即

Default constructor called instead of parametrized constructor

但在这种情况下,没有进行任何克隆或复制,即显式调用一个简单的基本构造函数。

这里的预期行为应该是参数化的 class D 构造函数应该始终被调用,但是当我创建 F 的共享指针时情况并非如此。有人能告诉我为什么以及会是什么吗正确的做法是强制classF走这条路 F->"default constructor" E->"default constructor " ->"parameterized D constructor called : 17".

本例中有趣的 class 是 F、E 和 D

F.h

#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_

E.h

#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_

D.h

#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_

虚拟继承的情况下,只有最派生的class初始化虚拟基础class。

所以在

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

虚拟基地 D 是从 E

构建的

然而,在

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

虚拟基础 D 是从 F ("ignoring" E) 构建的。