gpt4 book ai didi

c++ - CRTP继承中的基类 "friending"是否也会影响子类?

转载 作者:行者123 更新时间:2023-11-30 03:38:41 29 4
gpt4 key购买 nike

attempt to answer another question 中,我想出了一个方案来强制 CRTP 基类的子级在它们的构造函数中接受特定类型作为参数:使参数类型的构造函数 private,将 CRTP 基类分配为 friend,并将参数类型也声明为基类构造函数的参数。

但是,当我试图证明该方案通过访问冲突提供了所需的保护时,我发现即使参数类型的构造函数是私有(private)的,子类也能够构造它:

template <typename T>
class SingletonBase {
protected: class P { friend class SingletonBase<T>; P() = default; };
public:
SingletonBase(P) {}
};

class Logger: public SingletonBase<Logger> {
using BASE = SingletonBase<Logger>;
public:
Logger() : BASE{P{}} {} // WHY NO ACCESS VIOLATION?
};

compiles without error ,即使我预计会发生访问冲突。为什么?

最佳答案

Does “friending” the base class in CRTP inheritance affect the child class as well?

不,当然不是。友情不是世代相传的。为了说明这个问题,

首先,P::P() 是默认的默认构造函数,它是一个trivial default constructor。 .

其次,P{}value initialization (C++11 起),

(强调我的)

2) if T is a class type with a default constructor that is neither user-provided nor deleted (that is, it may be a class with an implicitly-defined or defaulted default constructor), the object is zero-initialized and then it is default-initialized if it has a non-trivial default constructor;

注意它只会是 zero initialized这里,不是default initializated . P 的私有(private)默认构造函数根本不会被调用。

If T is an non-union class type, all base classes and non-static data members are zero-initialized, and all padding is initialized to zero bits. The constructors, if any, are ignored.

如果您将其显式更改为默认初始化,则会出现访问冲突错误。

Logger() : BASE{P()} {} // error: calling a private constructor of class 'SingletonBase<Logger>::P
// ~~

一个简化的演示

class X { X() = default; };

int main()
{
X x1{}; // fine
X x2; // error: calling a private constructor of class 'X'
}

LIVE

解决方案

您可以提供一个用户定义的默认构造函数,这是一个非平凡的构造函数,以更改值初始化的行为。

template <typename T>
class SingletonBase {
protected:
class P {
friend class SingletonBase<T>;
P() {} // user-defined default constructor
};
public:
SingletonBase(P) {}
};

class Logger: public SingletonBase<Logger> {
using BASE = SingletonBase<Logger>;
public:
Logger() : BASE{P{}} {} // error: calling a private constructor of class 'SingletonBase<Logger>::P'
};

关于c++ - CRTP继承中的基类 "friending"是否也会影响子类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39423858/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com