繁体   English   中英

使用好友声明继承私有CRTP构造函数

[英]Inheriting private CRTP constructor using friend declaration

我很难理解从基类继承构造函数的正确行为。 在我的特殊情况下,我有一个带有私有构造函数的crtp基类,以防止基类的实例化(作为抽象类)。 现在,crtp-base与派生类建立了友谊,派生类通过using语句继承了基类构造函数。 这对于默认,复制和移动构造函数非常有效,但对自定义构造函数无效。 有没有一种方法可以实现而无需重新实现派生类中的所有构造函数?

#include <iostream>

template <typename d_t>
class base
{
    friend d_t;

    base()
    {
        std::cout << "base: ctor()\n";
    }
    base(base const & other) = default;
    base(base && other) = default;

    base(int)
    {
        std::cout << "base: ctor()\n";
    }
};

class derived: public base<derived>
{
public:

   using base<derived>::base;
};

int main()
{
   derived d{};
   derived d1{d};
   derived d2{std::move(d1)};
   // derived d3{1};  //does not compile!
}

编辑

AFAIK cppreference表示派生类中using声明的访问说明符不会更改构造函数的可访问性,这与其他成员函数不同。 但是我已经看到了这种代码的编译和运行,并且不确定我是否正确理解了使用声明。 当然,我将进一步研究其他代码,以了解发生了什么,但是我想知道是否有隐藏的东西可能会错过。

简短的答案是肯定的,只需在基类中将其公开即可。 继承的构造函数在派生类中具有与在基类中相同的可访问性。 无法在派生类中公开私有基类构造函数。

但是无论如何,抽象基类不能单独实例化。 无需将其构造函数设为私有。

CRTP与上述任何内容无关。 如果仅在friend声明中需要它,则可以不使用该模式。

class base
{
public:
  base()
  {    
  }

  base(int)
  {
    std::cout << "base: ctor()\n";
  }

  virtual void foo() = 0;
};

class derived: public base
{
public:
  using base::base;

  void foo() override
  {
    // details...
  }
};

int main()
{
  derived d{};
  derived d1{d};
  derived d2{std::move(d1)};
  derived d3{1};  //Works!!
}

有关cppreference的进一步阅读: using-declaration

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM