不能在C++中与虚拟继承的类交朋友

Can't friend a class that virtual inherits from it in C++

本文关键字:继承 交朋友 虚拟 C++ 不能      更新时间:2023-10-16

我想使只有一个类Der可以继承Base类。因此,我将Base的构造函数设为私有,并将Der添加为Base的友元:

struct Base {
 template<class T>
 friend struct Der;
 private:
  Base() = default;
};
template<class T>
struct Der : Base {};

但是另一个结构体DerDerDer继承,多次使用不同的模板参数。

struct DerDer : Der<int>, Der<char> {};

这是一个问题,因为现在有两个Base在层次结构中,所以解决方案是使Der实际上继承自Base:

template<class T>
struct Der : virtual Base {};

这现在打破了,我相信如果一个类实际上是继承的,那么最派生的类负责调用构造函数(不确定为什么)。这是一个问题,因为DerDer不是Base的朋友,因此不能访问它的构造函数。

我该如何解决这个问题?

(这似乎是一个实现细节,虚拟继承使最派生的类调用构造函数,所以朋友应该尊重这样做是正确的,这是编译器(或标准)中的一种错误)

一种选择是使用私有嵌套结构体来控制构造Base的权限。

struct Base {
    template<class T>
    friend struct Der;
private:
    struct Permission {};
public:
    Base(Permission) {}
    virtual ~Base() = default;
};
template <class T>
struct Der : public virtual Base {
protected:
    using Permission = Base::Permission;
public:
    Der() : Base(Permission{}) {}
};
struct DerDer : Der<int>, Der<char> {
    DerDer() : Base(Der<int>::Permission{}) {}
};

现在编写构造函数有点尴尬,但是构造Base的唯一方法是为某些T继承Der<T>

我该如何解决这个问题?

最简单的解决方案是使Base::Base()成为public的成员函数。